| 類 | 可變性 | 線程安全 | 性能 | 適用場景 |
|---|---|---|---|---|
| String | 不可變 | ✅ (不可變天然安全) | 拼接慢 (產生新對象) | 常量、少量拼接、Key 值 |
| StringBuffer | 可變 | ✅ (方法 synchronized) | 中等 | 多線程環境字符串操作 |
| StringBuilder | 可變 | ❌ | 最快 (JDK 5+ 推薦) | 單線程環境、大量拼接 |
// String 拼接產生多個對象
String s = "a" + "b" + "c"; // 編譯期優化為 "abc"
String s2 = "a";
s2 += "b"; // 運行期:new StringBuilder().append("a").append("b").toString()
// StringBuilder 高性能拼接
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) sb.append(i);
String result = sb.toString();
// 上界 extends T> - 只能讀,不能寫 (除 null)
List<? extends Number> list1 = new ArrayList<Integer>();
Number n = list1.get(0); // ✅ 讀取安全
// list1.add(1); // ❌ 編譯錯誤:無法確定具體類型
// 下界 super T> - 只能寫,讀出是 Object
List<? super Integer> list2 = new ArrayList<Number>();
list2.add(1); // ✅ Integer 是 Integer 父類
list2.add(new Integer(2)); // ✅
// Number n2 = list2.get(0); // ❌ 只能 Object n2 = list2.get(0);
// PECS 原則:Producer Extends, Consumer Super
// 只讀取用 extends,只寫入用 super,既讀又寫不用通配符
類初始化順序 (靜態) → 實例初始化順序:
class Parent {
static { System.out.println("1. Parent static"); }
{ System.out.println("2. Parent instance block"); }
Parent() { System.out.println("3. Parent constructor"); }
int p = 10;
}
class Child extends Parent {
static { System.out.println("4. Child static"); }
{ System.out.println("5. Child instance block"); }
Child() { System.out.println("6. Child constructor"); }
int c = 20;
}
public class Test {
public static void main(String[] args) {
new Child();
}
}
/*
輸出順序:
1. Parent static (父類靜態)
4. Child static (子類靜態)
2. Parent instance block (父類實例塊)
3. Parent constructor (父類構造器)
5. Child instance block (子類實例塊)
6. Child constructor (子類構造器)
*/
口訣:靜態先行 (父→子),實例跟進 (父塊→父構造→子塊→子構造)。
FileOutputStream fos = new FileOutputStream("test.txt");
fos.write('a'); // 參數 int,實際寫入低 8 位
fos.close();
// 文件內容:'a' (ASCII 97 = 0x61)
// 字符 'a' 自動提升為 int 97,write 取低 8 位寫入
// 等同於 fos.write(97);
關鍵點:write(int b) 只寫入參數的低 8 位 (b & 0xFF)。字符自動提升為 int 時保留 ASCII 值,故正確寫入字符。