不可變類別看似優雅,但頻繁修改時需不斷建立新物件,導致大量 GC 壓力。對 String 等類別代價過高。
建立可變夥伴類(Mutable),大量修改時切換使用,完成後再轉回不可變類別(Immutable2)。
//: Immutable2.java
class Mutable {
private int data;
public Mutable(int initVal) { data = initVal; }
public Mutable add(int x) { data += x; return this; }
public Mutable multiply(int x) { data *= x; return this; }
public Immutable2 makeImmutable2() { return new Immutable2(data); }
}
public class Immutable2 {
private int data;
public Immutable2(int initVal) { data = initVal; }
public int read() { return data; }
public boolean nonzero() { return data != 0; }
public Immutable2 add(int x) { return new Immutable2(data + x); }
public Immutable2 multiply(int x) { return new Immutable2(data * x); }
public Mutable makeMutable() { return new Mutable(data); }
// 純不可變方式:產生 4 個中間物件
public static Immutable2 modify1(Immutable2 y){
Immutable2 val = y.add(12);
val = val.multiply(3);
val = val.add(11);
val = val.multiply(2);
return val;
}
// 夥伴類方式:僅建立 2 個物件
public static Immutable2 modify2(Immutable2 y){
Mutable m = y.makeMutable();
m.add(12).multiply(3).add(11).multiply(2);
return m.makeImmutable2();
}
// ... main 測試代碼省略
} ///:~
modify1() 全程使用不可變類別,產生 4 個中間 Immutable2 物件(前三個變垃圾)。modify2() 先轉為 Mutable,連串修改無新物件,最後轉回,僅建立 2 個物件(Mutable + 結果 Immutable2)。