可變類與不可變類的區別
所謂不可變類:
是指當創建了這個類的實例后,就不允許修改它的屬性值。在JDK的基本類庫中,所有基本類型的包裝類,如Integer和Long類,都是不可變類,java.lang.String也是不可變類。
不可變類:
當你獲得這個類的一個實例引用時,你不可以改變這個實例的內容。不可變類的實例一但創建,其內在成員變量的值就不能被修改。
如何創建一個不可變類?
這道題90%以上的人都會被掛或者只回答一半對,來看:
1. 所有成員都是private
2. 不提供對成員的改變方法,例如:setXXXX
3. 確保所有的方法不會被重載。手段有兩種:使用final Class(強不可變類),或者將所有類方法加上final(弱不可變類)。
4. 如果某一個類成員不是原始變量(primitive)或者不可變類,必須通過在成員初始化(in)或者get方法(out)時通過深度clone方法,來確保類的不可變。
四點中少一點,回答失敗,來看一個例子:
public final class MyImmutableWrong { private final int[] myArray; public MyImmutableWrong(int[] anArray) { this.myArray = anArray; // wrong } public String toString() { StringBuffer sb = new StringBuffer("Numbers are: "); for (int i = 0; i < myArray.length; i++) { sb.append(myArray[i] + " "); } return sb.toString(); } }
以上不可變類書寫錯誤,為什么?違犯了第四點
正確的寫法:
public final class MyImmutableCorrect { private final int[] myArray; public MyImmutableCorrect(int[] anArray) { this.myArray = anArray.clone(); } public String toString() { StringBuffer sb = new StringBuffer("Numbers are: "); for (int i = 0; i < myArray.length; i++) { sb.append(myArray[i] + " "); } return sb.toString(); } }