一个非可变类是一个简单的类,它的实例不能被修改。非可变类的存在有许多的理由:非可变类比非可变类更加易于设计、实现和使用,它们更加的安全,不容易出错。
为了使一个类成为非可变类,要遵循一下五个原则:
1.不要提供任何会修改对象的方法。
2.保证没有可被子类改写的方法。通常将类定义成fianl,让它不能被继承。
3.使所有的域都是final的。显示的声明你的意图。
4.将所有的域都成为私有的。
5.保证对于任何可变组件的互斥访问。对于类中可变的对象,让其不能被访问。
定义如下非可变类:
final class Complex{ private final float re; private final float im; private Complex(float re, float im){ this.re = re; this.im = im; } public static Complex valueOf(float re, float im){ return new Complex(re, im); } public float realPart(){ return re;} public float imaginaryPart(){ return im;} public Complex add(Complex c){ return new Complex(re + c.re, im + c.im); } public Complex subtract(Complex c){ return new Complex(re - c.re, im - c.im); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Complex complex = (Complex) o; if (Float.compare(complex.re, re) != 0) return false; return Float.compare(complex.im, im) == 0; } @Override public int hashCode() { int result = (re != +0.0f ? Float.floatToIntBits(re) : 0); result = 31 * result + (im != +0.0f ? Float.floatToIntBits(im) : 0); return result; } @Override public String toString() { return "Complex{" + "re=" + re + ", im=" + im + '}'; } }
非可变对象比较简单,一个非可变对象可以只有一个状态,即最初被创建时刻的状态。所以,非可变对象本质上是线程安全的,他们不要求同步,可以被自由的共享。它还可以称为其他对象的组件。对于使用非可变的对象,我们可以通过静态工厂去获取,避免重复创建。
非可变类的缺点是,对于每一个不同的值都要求一个单独的对象,如果这样的操作过多,那么会带来性能的影响。非可变类String和BigInteger提供了公有的可变配套类,StringBuilder和BitSet
除非有很好的理由要让一个类成为可变类,否则就应该是非可变的。如果一个类不能被成非可变类,那么你仍然应该尽可能地限制它的可变性。并且,构造函数应该创建完全初始化的对象,所有的约束关系应该在这时候建立起来