不可變類:所謂的不可變類是指這個類的實例一旦建立完成後,就不能改變其成員變量值。如JDK內部自帶的不少不可變類:Interger、Long和String等。java
可變類:相對於不可變類,可變類建立實例後能夠改變其成員變量值,開發中建立的大部分類都屬於可變類。安全
不可變類的優勢:併發
1.線程安全ide
不可變對象是線程安全的,在線程之間能夠相互共享,不須要利用特殊機制來保證同步問題,由於對象的值沒法改變。測試
能夠下降併發錯誤的可能性,由於不須要用一些鎖機制等保證內存一致性問題也減小了同步開銷。ui
2.易於構造、使用和測試google
一個類的private的方法會隱式的申明爲final方法spa
package com.mmall.concurrency.example.immutable; import com.google.common.collect.Maps; import com.mmall.concurrency.annoations.NotThreadSafe; import lombok.extern.slf4j.Slf4j; import java.util.Map; @Slf4j @NotThreadSafe public class ImmutableExample1 { private final static Integer a = 1; private final static String b = "2"; private final static Map<Integer, Integer> map = Maps.newHashMap(); static { map.put(1, 2); map.put(3, 4); map.put(5, 6); } public static void main(String[] args) { // a = 2; // b = "3"; // map = Maps.newHashMap(); map.put(1, 3); log.info("{}", map.get(1)); } private void test(final int a) { // a = 1; } }
package com.mmall.concurrency.example.immutable; import com.google.common.collect.Maps; import com.mmall.concurrency.annoations.ThreadSafe; import lombok.extern.slf4j.Slf4j; import java.util.Collections; import java.util.Map; @Slf4j @ThreadSafe public class ImmutableExample2 { 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)); } }
package com.mmall.concurrency.example.immutable; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.mmall.concurrency.annoations.ThreadSafe; @ThreadSafe public class ImmutableExample3 { private final static ImmutableList<Integer> list = ImmutableList.of(1, 2, 3); private final static ImmutableSet set = ImmutableSet.copyOf(list); private final static ImmutableMap<Integer, Integer> map = ImmutableMap.of(1, 2, 3, 4); private final static ImmutableMap<Integer, Integer> map2 = ImmutableMap.<Integer, Integer>builder() .put(1, 2).put(3, 4).put(5, 6).build(); public static void main(String[] args) { System.out.println(map2.get(3)); } }