什么是不可變類
不可變類:所謂的不可變類是指這個類的實例一旦創(chuàng)建完成后,就不能改變其成員變量值。如JDK內(nèi)部自帶的很多不可變類:Interger、Long和String等。
可變類:可變類就是該類生成的實例的成員變量等是可以被改變的,大多數(shù)類基本都是可變類。
不可變類的優(yōu)勢
不可變類最大的優(yōu)勢就是線程安全,因為觸發(fā)線程不安全就是當一個變量是共享變量的時候,有多個線程同時訪問該變量,并且去修改,則就會觸發(fā)線程不安全。而不可變類由于內(nèi)容已經(jīng)不可變,只能讀取,所以就不會出現(xiàn)線程安全問題。
不可變類的設計原則
- 類必須是final型的,防止被繼承
- 類里面的成員變量是final型的,防止被修改,并且是private
- 成員變量不能暴露setter()方法,只暴露get()方法,防止被修改
- 通過構造函數(shù)初始化成員變量
- 成員變量的get方法,最好返回該變量的拷貝,防止變量外泄
String為何是不可變類
String的源碼如下:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
/**
* Class String is special cased within the Serialization Stream Protocol.
*
* A String instance is written into an ObjectOutputStream according to
* <a href="{@docRoot}/../platform/serialization/spec/output.html">
* Object Serialization Specification, Section 6.2, "Stream Elements"</a>
*/
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
void getChars(char dst[], int dstBegin) {
System.arraycopy(value, 0, dst, dstBegin, value.length);
}
/** ......*/
}
可以看到,String的源碼里面有很多個不可變的特點
- 類被final修飾,不會被繼承
- 成員變量都用final以及private修飾,表示一經(jīng)初始化,就不會被改變
- 源碼里面沒有暴露對成員變量的setter方法
- 對于getter方法,如上面的getChars方法,返回的是copy后的值
- 在構造函數(shù)就對成員變量進行初始化