Java 可變物件與不可變物件
阿新 • • 發佈:2018-12-08
可變物件與不可變物件
概念1
- 不可變物件(Immutable Objects)即物件一旦被建立它的狀態(物件的資料,也即物件屬性值)就不能改變,任何對它的改變都應該產生一個新的物件
String str = "a" ;
str = "b" ;
// 兩處的 str 不是同一個物件 == 判斷 或輸出 物件地址資訊 不同
- 可變物件(Mutable Objects):相對於不可變類,可變類建立例項後可以改變其成員變數值,開發中建立的大部分類都屬於可變類
- 不可變物件的類即為不可變類(Immutable Class)。JAVA平臺類庫中包含許多不可變類,如String、基本型別的包裝類、BigInteger和BigDecimal等
不可變類
- 類不可被繼承:
- 將類宣告為final, 或者使用靜態工廠並宣告構造器為private。
- 如果類可以被繼承會破壞類的不可變性機制,只要繼承類覆蓋父類的方法並且繼承類可以改變成員變數值,那麼一旦子類以父類的形式出現時,不能保證當前類是否可變。
- 使用private和final修飾符來修飾該類的屬性
注:如果成員屬性為可變物件屬性,不要使這些物件改變:
1)不要提供更改可變物件的方法,如 set 方法
2)不要共享對可變物件的引用,不要儲存傳給構造器的外部可變物件的引用。因為引用可變物件的成員變數和外部可變物件的引用指向同一塊記憶體地址,使用者可以在不可變類之外通過修改可變物件的值
public final class MyImmutableDemo {
private final int[] myArray;
public MyImmutableDemo(int[] array) {
this.myArray = array.clone(); // 構造器的入參為引用資料型別時使用克隆
// 當入參改變時不會影響構造器內部的資料
}
}
- 不要提供任何可以修改物件狀態的方法(不僅僅是set方法, 還有任何其它可以改變狀態的方法)
- 類中通過 get 返回的屬性是引用資料型別,也要返回克隆後的屬性,防止呼叫方改變引用物件的資料
不可變物件
-
優點:
- 構造、測試和使用都很簡單
- 不可變物件是執行緒安全的,線上程之間可以相互共享,不需要利用特殊機制來保證同步問題,因為物件的值無法改變。可以降低併發錯誤的可能性,因為不需要用一些鎖機制等保證記憶體一致性問題也減少了同步開銷。
- 不可變物件可以被重複使用,可以將它們快取起來重複使用,就像字串字面量和整型數字一樣。可以使用靜態工廠方法來提供類似於valueOf()這樣的方法,它可以從快取中返回一個已經存在的Immutable物件,而不是重新建立一個。
-
缺點
- 不可變物件最大的缺點就是建立物件的開銷,因為每一步操作都會產生一個新的物件,製造大量垃圾,由於他們不能被重用而且對於它們的使用就是”用“然後”扔“,會創造很多的垃圾,給垃圾收集帶來很大的麻煩