使可变性最小化
使类不可变的条件,如String
1. 不要提供任何改变对象状态的方法setter
2. 保证类不会被扩展
3. 确保所有的域都是final的
4. 确保所有的域都是私有的
5. 确保客户端无法访问可变对象的引用
不可变类的特点:
1. 不可变类比较简单
2. 不可变类本身就是线程安全的
3. 无需保护性拷贝
4. 不仅可以共享不可变对象,还可以共享他们的内部信息。如BigInteger中的negate()方法,直接访问内部域
不可变类唯一的缺点:
对于每个不同的值都需要一个独立的对象,特别是在多步骤的情景中。
解决方法一是预测多步骤的地方,将其转为基本类型来操作;二是提供一个不可变类对应的公有的可变配置类
类绝对不允许被子类化,另外一种替代的灵活方法是公有的静态工厂方法(即把构造器私有化,提供一个公有的静态方法调用私有的构造器返回对象)
在编写BigInteger和BigDecimal时,类不可变的要求:"保证类不能被扩展"还没有被广泛的理解,所以在使用BigInteger和BigDecimal时,首先要判断这个对象是不是来自于不可信的子类
public static BigInteger safeInstance(BigInteger val) { if (val.getClass() != BigInteger.class) { return new BigInteger(val.toByteArray()); } return val; }
坚决不要为每个类的get方法写一个对应的set方法。除非有很好的理由让这个类变成可变的,否则它就应该是不可变的。
构造器应该建立起完全初始化的对象,并建立起所有的约束条件。不要在构造器或者公有的静态工厂方法以外提供“重新初始化”的方法。