Java里包含很多不可变的类,如String,Boolean,Integer,这些类的优点包括:
1.简单
2.线程安全
3.可作为Map的key或集合元素
创建不可变类的基本原则包括:
1.不提供任何可修改对象状态的方法,如setter方法
2.不能继承
3.使用final修饰所有属性
4.使用private修饰所有属性
5.不要引用任何可被外部修改的可变的对象(可引用此对象的clone版本)
6.不要返回任何可变的对象给外部引用
7.需要处理序列化创建不可变类的对象的问题(见后面章节)
一个简单不可变类的示例:
public class Complex {
//使用private final 修饰属性
private final double re;
private final double im;
//私有构造函数,避免类被继承
private Complex(double re,double im){
this.re=re;
this.im=im;
}
//提供静态工厂方法,用于创建对象
public static Complex vlaueOf(double re,double im){
return new Complex(re, im);
}
//每个业务方法返回一个新对象
public Complex add(Complex c){
return Complex.vlaueOf(re+c.re, im+c.im);
}
}
使用不可变类的唯一缺点是:针对不同的值,需要创建一个对应的不可变类的对象,这可能导致运算时性能低,内存消耗大,解决此问题的方法包括:
1.提供对应的可变类,如String对应的可变类StringBuilder,StringBuffer。BigInteger对应有一个package-private的可变类(用于提高计算性能)
2.提供常量不可变对象,如:
public static final Complex ZERO=new Complex(0, 0);
public static final Complex ONE=new Complex(1, 0);
3.在静态工厂方法里使用缓存的值或不可变对象,此方式可能要求不要使用final修饰需要缓存的属性