Java 基礎系列:不變性

1.1 定義

  不可變類(Immutable Objects):當類的實例一經建立,其內容便不可改變,即沒法修改其成員變量。緩存

  可變類(Mutable Objects):類的實例建立後,能夠修改其內容。安全

  Java 中八個基本類型的包裝類和 String 類都屬於不可變類,而其餘的大多數類都屬於可變類。多線程

  ps: 某個對象在被建立後其狀態就不能被修改,那麼這個對象就稱爲不可變對象,不可變對象必定是線程安全的。不可變對象很簡單。他們只有一種狀態,而且該狀態由構造函數來控制。函數

  須要特別注意的是,不可變類的不可變是指該類的實例不可變而非指向該實例的引用的不可變性能

1.2 充分條件

當知足如下條件時,對象纔是不可變的:this

(1)對象建立之後其狀態就不能改變;spa

(2)對象的全部域都是final類型;線程

(3)對象是正確創造的(在對象建立期間,this引用沒有溢出)。指針

1.3 特徵

一個不可變類的定義應當具有如下特徵:對象

  1. 全部成員都是 private final 的
  2. 不提供對成員的改變方法,例如:setXXXX
  3. 確保全部的方法不會被重載。手段有兩種:使用final Class(強不可變類),或者將全部類方法加上final(弱不可變類)。
  4. 若是某一個類成員不是基本類型(primitive type)或不可變類,必須經過在成員初始化(in)或者getter方法(out)時經過深度拷貝(即複製一個該類的新實例而非引用)方法,來確保類的不可變。
  5. 若是有必要,重寫hashCode和equals方法,同時應保證兩個用equals方法判斷爲相等的對象,其hashCode也應相等。

1.4 優缺點

1. 優勢:效率和安全。

  • 效率(拷貝地址+緩存)

      1. 當一個對象是不可變的,那麼須要拷貝這個對象的內容時,就不用複製它的自己而只是複製它的地址,複製地址(一般一個指針的大小)只須要很小的內存空間,具備很是高的效率。同時,對於引用該對象的其餘變量也不會形成影響。

      2. 不變性保證了hashCode 的惟一性,所以能夠放心地進行緩存而沒必要每次從新計算新的哈希碼。而哈希碼被頻繁地使用, 好比在hashMap 等容器中。將hashCode 緩存能夠提升以不變類實例爲key的容器的性能。

  • 線程安全

      在多線程狀況下,一個可變對象的值極可能被其餘進程改變,這樣會形成不可預期的結果,而使用不可變對象就能夠避免這種狀況同時省去了同步加鎖等過程,所以不可變類是線程安全的

2. 缺點:不可變類的每一次「改變」都會產生新的對象,所以在使用中不可避免的會產生不少垃圾

相關文章
相關標籤/搜索