String s = "Hello world!";
這行程式碼宣告的是一個指向 String 物件的引用變數,名為 s,目前指向內容為 "Hello world!" 的 String 物件。並未建立新物件。若接著寫 String string = s;,只是多了一個指向同一物件的引用。
== vs equals()== 比較的是變數值:基本型別比值,引用型別比記憶體位址。equals() 比較的是物件內容,但預設實現同 ==,需類別覆寫才有語意(如 String、包裝類)。String a = new String("foo");
String b = new String("foo");
a == b; // false(不同位址)
a.equals(b); // true(內容相同)
警示:使用基於雜湊的集合(HashSet/Map)時,務必確認類別正確覆寫 equals() 與 hashCode()。
String 是不可變的。s = s + " world!" 實際上是建立新 String 物件,s 重新指向新物件,舊物件仍在記憶體中(等待 GC)。頻繁修改字串請用 StringBuffer/StringBuilder。
最佳實踐:
// 好:直接指向字串常量池同一物件
s = "Initial Value";
// 差:每次 new 都建立新物件,效能差
s = new String("Initial Value");
final 到底修飾什麼?final StringBuffer a = ...; a = b; // 編譯錯誤final StringBuffer a = ...; a.append("!"); // 編譯通過陷阱:final 無法保證物件狀態不變,多執行緒共享 final 物件時仍需同步。
| 變數型別 | 初始化時機 | 預設值 |
|---|---|---|
| 類屬性 | 建立實例時 | 0/0.0/false/'\u0000'/null |
| static 屬性 | 類載入時(首次使用) | 同上 |
| 區域變數 | 必須顯式初始化,否則編譯錯誤 | 無 |
| 方法參數 | 呼叫時傳入值即為初始值 | 無 |
區域變數規則:所有執行路徑在使用前必須賦值(含 try/if 分支)。
instanceof 是什麼?二元運算子,測試左側物件是否為右側類/介面的實例,回傳 boolean。
String s = "test";
boolean b = s instanceof Object; // true
應用場景:多型無法涵蓋時的型別判斷(如訪問者模式),但優先考慮方法多載/覆寫實現多型,避免退化為程序式判斷。
這六大觀念貫穿 Java 核心語意:引用機制、比較語意、不可變設計、final 真義、初始化規範、型別檢查。吃透它們,能避開 80% 的初階坑,寫出更正確、高效的程式碼。