- 类添加final修饰符,保证类不被继承。
如果类可以被继承会破坏类的不可变性机制,只要继承类覆盖父类的方法并且继承类可以改变成员变量值,那么一旦子类以父类的形式出现时,不能保证当前类是否可变。 2. 保证所有成员变量必须私有,并且加上final修饰
通过这种方式保证成员变量不可改变。但只做到这一步还不够,因为如果是对象成员变量有可能再外部改变其值。所以第4点弥补这个不足。 3. 不提供改变成员变量的方法,包括setter
避免通过其他接口改变成员变量的值,破坏不可变特性。 4. 通过构造器初始化所有成员,进行深拷贝(deep copy)
如果构造器传入的对象直接赋值给成员变量,还是可以通过对传入对象的修改进而导致改变内部变量的值。例如:
public final class ImmutableDemo {
private final int[] myArray;
public ImmutableDemo(int[] array) {
this.myArray = array; // wrong
}
}
这种方式不能保证不可变性,myArray和array指向同一块内存地址,用户可以在ImmutableDemo之外通过修改array对象的值来改变myArray内部的值。 为了保证内部的值不被修改,可以采用深度copy来创建一个新内存保存传入的值。正确做法:
public final class MyImmutableDemo {
private final int[] myArray;
public MyImmutableDemo(int[] array) {
this.myArray = array.clone();
}
}
- 在getter方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝
这种做法也是防止对象外泄,防止通过getter获得内部可变成员对象后对成员变量直接操作,导致成员变量发生改变。