Java 基础系列:不变性
1.1定義
不可變類(Immutable Objects):當(dāng)類的實(shí)例一經(jīng)創(chuàng)建,其內(nèi)容便不可改變,即無(wú)法修改其成員變量。
可變類(Mutable Objects):類的實(shí)例創(chuàng)建后,可以修改其內(nèi)容。
Java 中八個(gè)基本類型的包裝類和 String 類都屬于不可變類,而其他的大多數(shù)類都屬于可變類。
ps:某個(gè)對(duì)象在被創(chuàng)建后其狀態(tài)就不能被修改,那么這個(gè)對(duì)象就稱為不可變對(duì)象,不可變對(duì)象一定是線程安全的。不可變對(duì)象很簡(jiǎn)單。他們只有一種狀態(tài),并且該狀態(tài)由構(gòu)造函數(shù)來(lái)控制。
需要特別注意的是,不可變類的不可變是指該類的實(shí)例不可變而非指向該實(shí)例的引用的不可變。
1.2充分條件
當(dāng)滿足以下條件時(shí),對(duì)象才是不可變的:
(1)對(duì)象創(chuàng)建以后其狀態(tài)就不能改變;
(2)對(duì)象的所有域都是final類型;
(3)對(duì)象是正確創(chuàng)造的(在對(duì)象創(chuàng)建期間,this引用沒(méi)有溢出)。
1.3特征
一個(gè)不可變類的定義應(yīng)當(dāng)具備以下特征:
所有成員都是 private final 的
不提供對(duì)成員的改變方法,例如:setXXXX
確保所有的方法不會(huì)被重載。手段有兩種:使用final Class(強(qiáng)不可變類),或者將所有類方法加上final(弱不可變類)。
如果某一個(gè)類成員不是基本類型(primitive type)或不可變類,必須通過(guò)在成員初始化(in)或者getter方法(out)時(shí)通過(guò)深度拷貝(即復(fù)制一個(gè)該類的新實(shí)例而非引用)方法,來(lái)確保類的不可變。
如果有必要,重寫(xiě)hashCode和equals方法,同時(shí)應(yīng)保證兩個(gè)用equals方法判斷為相等的對(duì)象,其hashCode也應(yīng)相等。
1.4優(yōu)缺點(diǎn)
1. 優(yōu)點(diǎn):效率和安全。
效率(拷貝地址+緩存)
1. 當(dāng)一個(gè)對(duì)象是不可變的,那么需要拷貝這個(gè)對(duì)象的內(nèi)容時(shí),就不用復(fù)制它的本身而只是復(fù)制它的地址,復(fù)制地址(通常一個(gè)指針的大小)只需要很小的內(nèi)存空間,具有非常高的效率。同時(shí),對(duì)于引用該對(duì)象的其他變量也不會(huì)造成影響。
2.不變性保證了hashCode 的唯一性,因此可以放心地進(jìn)行緩存而不必每次重新計(jì)算新的哈希碼。而哈希碼被頻繁地使用, 比如在hashMap 等容器中。將hashCode 緩存可以提高以不變類實(shí)例為key的容器的性能。
線程安全
在多線程情況下,一個(gè)可變對(duì)象的值很可能被其他進(jìn)程改變,這樣會(huì)造成不可預(yù)期的結(jié)果,而使用不可變對(duì)象就可以避免這種情況同時(shí)省去了同步加鎖等過(guò)程,因此不可變類是線程安全的。
2. 缺點(diǎn):不可變類的每一次“改變”都會(huì)產(chǎn)生新的對(duì)象,因此在使用中不可避免的會(huì)產(chǎn)生很多垃圾。
總結(jié)
以上是生活随笔為你收集整理的Java 基础系列:不变性的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 别克阅朗1.3t精英款适合什么机油?
- 下一篇: lstat函数的使用【学习笔记】