不可改变类是其实例对象不可改变,有人可能会想这还不简单,我们不提供改变对象
内部状态的API不就完了,没错,这是一个很重要的一条,但还有很多注意点
首先为什么要创建不可改变的类?
不可改变类比可变类更加易于设计、实现和使用。它们不容易出错,且更加安全,在Java平台有很多不可改变类,如:String , 基本类型包装类、BigInteger BigDecimal
为使一个类不可改变,遵守下面五条规则:
1.不要提供任何会修改对象状态的方法
2.保证类不会被扩展(定义为final 类,也可以提供私有构造,然后提供静态工厂方法)
3.使所有的域都是final
4.使所有的域都是私有的
5.确保对于任何可变组件的互斥访问(如果类具有指向可变对象的域,则必需确保该类的客户端无法获得指向这些对象的引用)
然后不可变域也有不好的地方,就是第次修改都会产生一个新的对象,这将会大大影响
效率,我们可以考虑下面的情况 :
Integer sum = 0;
for(int i=0;i<100000;i++)
sum+=i;
这样下来,我们可想而知,系统里将会产生多少个Integer 对象,这将会大大影响效率,
其实Integer 在这方面已经做出来了优化,具体方案如下:
1.我们可以把经常使用到的对象提供给公有final 对象,如果BigInteger 中的ONE、TEN、zero
2.我们可以用一个静态工厂方法,将频繁使用的对象缓存起来了,这样每次我们调用的时候就可以直接返回缓存起来的值,而不用再次去创建相同的对象,下面是Integer中的做法,它是将一个字节所表示的有符号整形数据,而它的缓存则是放在了一个私有的静态内部类里面
private static class IntegerCache {
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
下面是静态工厂方法:
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}