Java 領域流傳著許多看似合理實則錯誤的認知,甚至滲透進面試題庫。本文精選 10 個高階誤區,涵蓋內存模型、並發、性能優化、時間處理、隨機數、浮點數、JIT 優化等核心領域,附代碼驗證與字節碼級解析,助你建立精確心智模型。
System.exit(0) 會跳過 finally?System.setSecurityManager(new SecurityManager() {
public void checkExit(int status) { throw new ThreadDeath(); }
});
try {
System.exit(0);
} finally {
System.out.println("In the finally block"); // 會執行!
}
真相:ThreadDeath 是 Error 子類,會穿透 catch 塊但**不阻止 finally 執行**。安全管理器拋出異常中斷退出流程,finally 正常跑完。
String str = "Hello" 中 str 是對象?錯誤。Java 變量只有基本類型和引用類型,**變量永遠不是對象**。str 是指向字符串對象的引用。str == text 比較引用地址而非內容。
不同。C++ 指不可達內存無法釋放;Java 中不可達對象會被 GC 回收。Java 「內存洩漏」指**本應回收的對象因被集合/緩存/監聽器持有強引用而無法回收**,如未清理的 List、Map、ThreadLocal。
無序難,有序易。亂扔代碼進線程池當然難。遵循:線程封閉、不可變對象、執行器框架、併發集合、同步器、非阻塞算法——團隊統一規範,難度大幅降低。
錯誤。整數加法 ~1ns、內存訪問 ~100ns、取模 ~10ns、控制台輸出 ~1ms。**優化應針對昂貴操作**(I/O、鎖、GC、網絡),而非納秒級運算。瓶頸在硬體時,軟件優化無效。
偽隨機。Random 基於線性同餘算法,種子固定則序列固定。安全場景必須用 SecureRandom。
誤區。浮點數誤差**確定性、可預測、可控**。同樣操作產生相同誤差。合理捨入(BigDecimal 或 Math.round(x*100)/100.0)下,浮點數效能碾壓 BigDecimal 百倍且產生更少臨時對象。
動態變化。倫敦 1970 年曾用夏令時(GMT+1),莫斯科 2011 年從 GMT+3 改為 GMT+4。歷史時間計算必須用 ZoneId/ZonedDateTime (Java 8+) 而非固定偏移量。
不一定。JIT 可能將熱點循環中的非 volatile 字段**內聯為常量**(寄存器緩存),導致其他線程修改永遠不可見。加 volatile 或同步塊可阻止此優化。
大量錯誤/過時。許多題庫 10 年未更新,與現代 JDK 脫節。推薦參考 StackOverflow(同行審核機制),避開「玫瑰印度」類低質量站點。
保持批判性思維,親自驗證,才是技術成長的正道。