并发之不可变对象
并发之不可变对象
什么是不可变对象
不可变对象:一个对象的状态在对象被创建之后就不再变化。不可变对象对于缓存是非常好的选择,因为你不需要担心它的值会被更改。
必须满足三个条件才可以称之为不可变对象
- 对象创建完成后其状态不可修改。(数据私有并且没有对状态的修改方法)
- 对象的所有域都是final不可变的.(也可以不是final的但是不能有指向可变域的引用逸出)
- 对象时正确创建的,即创建对象没有this对象逸出。
final介绍final finally finalize的区别
示例
final定义不可变对象
修饰成员变量
@Slf4j
public class finalExample {
private final StringBuffer sb = new StringBuffer("Hello");
@Test
public void finalStringBufferTest(){
sb.append(" World");
log.info("{}",sb.toString());
}
private static final Map<Integer,Integer> map = new HashMap<>();
static {
map.put(1,2);
map.put(2,3);
map.put(3,4);
}
@Test
public void finalMapTest(){
log.info("{}",map.toString());
map.put(5,1);
log.info("{}",map.toString());
}
}
final修饰方法的形参
private void finalTest(final int x){
log.info("{}",x);
}
其他不可变处理变量的方式
Collections工具包中unmodifiableMap方法
public class OtherImmutableExample {
private static Map<Integer,Integer> map = new HashMap<>();
static {
map.put(1,2);
map.put(2,3);
map.put(3,4);
map = Collections.unmodifiableMap(map);
}
@Test
public void collectionsTest(){
map.put(1,3);
}
}
会抛出异常
谷歌的common里的immutable中的方法
private static final ImmutableMap<Integer,Integer> imap = ImmutableMap.of(1,2);
@Test
public void immutableMapTest(){
imap.put(1,3);
}
会抛出异常
总结
不可变对象对于常规类型的不可变对象可以使用final修饰,对于集合相关的不可变对象可以使用java的collections或者谷歌的common处理。