一、不可变对象要满足以下几个条件:(1)对象创建以后状态不能修改;(2)对象所有域都时final类型;(3)对象是正确创建的(this引用没有逸出)
我们来介绍一下final,Collectons.unmodifiableXXX,Guava的ImmutableXXX
二、final
(1)修饰类:不能被继承
(2)修饰方法:锁定方法不被继承类修改
(3)修饰变量:基本类型变量,引用类型变量
一个类的private方法会隐式被指定为final方法。
final修饰变量,对于基本数据类型,数值在初始化之后不能被修改;如果是引用类型变量,则在对其初始化之后,便不能让它再【指向】另外一个对象。
final修饰的引用类型,只是不能指向另一个引用,但是里面的值可以修改。
三、Collectons.unmodifiableXXX,Guava的ImmutableXXX
指Collection/Set/List/Map等。
经过上面两个处理之后,变量是不可以被修改的。
看一下Collectons.unmodifiableXXX例子:
@Slf4j
public class UnmodifiableExample {
private static Map<Integer, Integer> map = Maps.newHashMap();
static {
map.put(1, 2);
map.put(3, 4);
map.put(5, 6);
map = Collections.unmodifiableMap(map);
}
public static void main(String[] args) {
map.put(1, 3);
log.info("{}", map.get(1));
}
}
下面的map.put会报错。
看unmodifiableXXX源码:
它是 生成了一个新的 map , 在这个新的 map 里面,一旦初始化好了之后,这里面的很多方法都是不允许操作的,直接把里面的方法做成异常抛出,这样就把普通的 map 变成了不可修改的 map 。