秦小波《編寫高質量代碼:改善 Java 程序的 151 個建議》共 12 章 151 條建議。第 1-3 章針對語法基礎(51 條),第 4-9 章聚焦 JDK API(80 條),第 10-12 章覆蓋性能、工具框架、編碼風格(20 條)。建議細讀慢悟,而非速讀堆砌。
反例: long i = 1l; (小寫 L 極似數字 1)
後果: 讀者誤以為賦值 11,實際為 1,導致邏輯誤解。
規範:
1L。l、大寫 O 單獨作為變量名。l 強制大寫,O 需添加註釋說明。反例:
interface Constant {
public static final int RAND_CONST = new Random().nextInt(); // 運行期賦值
}
問題: 每次訪問 RAND_CONST 均重新生成隨機數,違背「常量編譯期確定、運行期不變」原則,極大降低可讀性與可維護性。
原則: final static 常量必須在編譯期確定值,禁止運行期動態賦值。隨機種子、序列號生成請使用專用工具類方法,勿偽裝為常量。
反例:
String str = String.valueOf(80 < 100 ? 90 : 100); // 兩側皆 int
String str1 = String.valueOf(80 < 100 ? 90 : 100.0); // 第二操作數為 double
結果: str.equals(str1) == false。因三元運算符要求二三操作數類型一致,編譯器將 90 提升為 90.0,導致 str1 為 "90.0"。
規則: 明確三元運算符類型提升規則(int→long→float→double),編寫時保證兩側顯式類型一致,避免隱式轉換產生難以發現的 Bug。
場景:
void calPrice(int price, int discount); // 簡單折扣
void calPrice(int price, int... discounts); // 多重折扣
調用歧義: calPrice(499, 75) 既匹配第一個(int, int),也匹配第二個(int, int[])。編譯器優選固定參數版本(原始類型優於數組),但這屬於「編譯器猜測」,極易誤導維護者。
建議: 避免可變參數方法與固定參數方法構成重載關係;若必須共存,方法名語義區分(如 calSimplePrice/calCompoundPrice)。
重載衝突:
void methodA(String str, Integer... is);
void methodA(String str, String... strs);
調用陷阱:
methodA("china"):兩個方法均匹配(可變參數長度可為 0),編譯報「方法模糊」。methodA("china", null):null 無類型,雙方法均匹配,編譯報錯。修正: 顯式聲明數組類型:
String[] strs = null;
methodA("china", strs); // 編譯器明確類型為 String[],匹配第二個方法
原則: 調用者不應隱藏實參類型;設計者應遵循 KISS 原則,避免同名可變參數重載造成調用歧義。