不变类是实例不能被修改的类,每个实例域中的所有信息在构造的时候就初始化完成并且在整个生命周期内固定不变,
复制代码
不可变的类比可变类更加容易设计,实现和使用,且不容易维护,以后的工作中应该尽可能的让类的可变性最小,java中的String,Interger这种包装类,BitInteger都是不可变类。 有几条原则: 1)不提供修改对象状态的方法 2)类不被扩展,一般将类定义成final,这个类便不可以再被继承 3)所有的域都成为final的,有一点好处,如果域是final的,在缺乏同步机制的情况下,当多个线程并发访问时也不需要担心并发问题 4)使使所有域都成为私有的,这样可以防止客户端获得被域引用的可变对象的权限,当然,从技术上讲,不可变的类具有公有的final域,且只要指向的对象不可变就没有什么问题,但是这样以后你想在访问该域的时候做一些限制就很难了,最好是提供get方法。 5)确保对于任何可变组件的互斥访问。
下面就来看一下BigInteger或者Integer中哪些设计符合上面这些原则吧
1)这条看源码没有任何方法可以修改域
2)BigInteger不是final的,这里是java设计的一个遗憾,为了向后兼容,一直没被修复,BigInteger大多数可以被覆盖
为什么说不是final的BigInteger会存在问题?
因为可能有个不可信任的子类继承了BigInteger,如果一个引用指向了该子类,但是你实际想要的是BigInteger,就会存在问题
3)Integer满足
**
* The int value represented by this Integer
*/
private final int value;
4)上面可以看出Integer满足
5)由于Integer,BigInteger中都没有指向可变对象的域,假设有的话.可以使用保护性拷贝技术
复制代码
不可变对象本质上市线程安全,所以不可变对象可以被自由的共享,因为,对于频繁使用到的值,为它们提供公有的静态final常量,可以尽可能的重用现有的实例。例如BigInteger中的
/** The {@code BigInteger} constant 0. */ public static final BigInteger ZERO = new BigInteger(0, 0);
/** The {@code BigInteger} constant 1. */
public static final BigInteger ONE = new BigInteger(1, 1);
复制代码