对于Map等集合类型,我们只能对于其引用不能被再次初始化,而其中的值则可以变化,比如:
private static final Map map = Maps.newHashMap();
static {
map.put(1, "one");
map.put(2, "two");
}
public static void main(String[] args) {
map.put(1,"three");
log.info("{}", map.get(1));
}
输出:
22:45:01.582 [main] INFO com.tim.concurrency.example.immutable.ImmutableExample - three
分析上述代码可知map的值由原来key为1,value为one,被改为value为three。因此,此map是域不安全的。
改进方法(通过Collectionsf方法):
static {
map.put(1, "one");
map.put(2, "two");
map = Collections.unmodifiableMap(map);
}
public static void main(String[] args) {
log.info("{}", map.get(1));
}
分析:
上述map如果再被put,则会报异常,map.put(1, "three");则会报异常。
static {
map.put(1, "one");
map.put(2, "two");
map = Collections.unmodifiableMap(map);
}
public static void main(String[] args) {
map.put(1, "three");
log.info("{}", map.get(1));
}
上述代码会导致下面异常:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableMap.put(Collections.java:1457)
at com.tim.concurrency.example.immutable.ImmutableExample.main(ImmutableExample.java:27)
分析:上述map是域安全,被初始化之后,不能被修改了。
补充(利用Collections和Guava提供的类可实现的不可变对象):
Collections.unmodifiableXXX:Collection、List、Set、Map...
Guava:ImmutableXXX:Collection、List、Set、Map...
private final static ImmutableList list = ImmutableList.of(1, 2, 3); // 这样被初始化之后 list是不能被改变
private final static ImmutableSet set = ImmutableSet.copyOf(list); // 这样被初始化之后set是不能被改变的
public static void main(String[] args) {
list.add(123);
set.add(222);
}
}
上述代码中的list和set不能再被改变。
注意:guava中的map的写法有点不一样如下:
private final static ImmutableMap map = ImmutableMap.of(1,2,3,4,5, 6);
private final static ImmutableMap map2 = ImmutableMap.builder().put(1,2).put(3,4).put(5,6).build();