BIG阳
什么是不可变的对象?不变对象是在实例化后不会改变状态的对象。如何使对象不变?通常,可以通过定义一个不暴露任何成员且没有任何设置方法的类来创建不可变对象。以下类将创建一个不可变的对象:class ImmutableInt { private final int value; public ImmutableInt(int i) { value = i; } public int getValue() { return value; }}从上面的示例可以看出,ImmutableInt只能在实例化对象时设置the的值,并且通过仅使用getter(getValue),在实例化后不能更改对象的状态。但是,必须注意,该对象引用的所有对象也必须是不可变的,否则可能会更改该对象的状态。例如,允许对数组的引用或ArrayList通过getter获取将允许通过更改数组或集合来更改内部状态:class NotQuiteImmutableList<T> { private final List<T> list; public NotQuiteImmutableList(List<T> list) { // creates a new ArrayList and keeps a reference to it. this.list = new ArrayList(list); } public List<T> getList() { return list; }}上面的代码的问题在于,ArrayList可以通过获取getList和操纵它们,从而导致对象本身的状态被改变,因此,它不是不变的。// notQuiteImmutableList contains "a", "b", "c"List<String> notQuiteImmutableList= new NotQuiteImmutableList(Arrays.asList("a", "b", "c"));// now the list contains "a", "b", "c", "d" -- this list is mutable.notQuiteImmutableList.getList().add("d");解决此问题的一种方法是从getter调用时返回数组或集合的副本:public List<T> getList() { // return a copy of the list so the internal state cannot be altered return new ArrayList(list);}不变性的优点是什么?不变性的优点在于并发。在可变对象中很难保持正确性,因为多个线程可能试图更改同一对象的状态,从而导致某些线程看到同一对象的不同状态,具体取决于读取和写入对象的时间宾语。通过拥有一个不可变的对象,可以确保所有正在查看该对象的线程都将看到相同的状态,因为不可变的对象的状态不会改变。