一个非可变类是一个简单的类,它的实例不能被修改。非可变类的存在有许多的理由:非可变类比非可变类更加易于设计、实现和使用,它们更加的安全,不容易出错。
为了使一个类成为非可变类,要遵循一下五个原则:
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
除非有很好的理由要让一个类成为可变类,否则就应该是非可变的。如果一个类不能被成非可变类,那么你仍然应该尽可能地限制它的可变性。并且,构造函数应该创建完全初始化的对象,所有的约束关系应该在这时候建立起来