Java多線程——不可變對象

不可變對象條件

對象須要知足一下三個條件纔是不可變對象:工具

一、對象建立之後其狀態就不能修改this

二、對象全部域都是final類型spa

三、對象是正確建立的(對象在建立期間,this引用沒有溢出)code

簡而言之就是將類聲明爲final,將全部的成員聲明爲私有的,對變量不提供set方法。將全部可變的成員聲明爲final。在get方法中不返回對象自己,而是克隆對象的拷貝。(可參考String類)。對象

final關鍵字

final關鍵字可修飾類、方法和變量。在修飾類時,這個類是不容許被繼承。final類中的方法會被隱式的被指定爲final方法。修飾方法是爲了鎖定方法不被繼承類修改,即final方法不容許被修改,一個類的private方法會被隱式指定爲final類型。final修飾變量可分爲兩種狀況。1、修飾基本數據類型時,一旦被final修飾,這個變量的數值就不能被修改了。2、修飾引用類型變量時,則是讓它在初始化以後就不能指向其餘對象(可修改該引用變量的成員變量)。例如:blog

@Slf4j
public class ImmutableExample1 {
 
    private final static Integer a = 1;
    private final static String b = "2";
    private final static Map<Integer, Integer> map = new HashMap();
 
    static {
        map.put(1, 2);
        map.put(3, 4);
        map.put(5, 6);
    }
 
    public static void main(String[] args) {
        map.put(1, 3);
        log.info("{}", map.get(1));
    }
}

雖然map聲明爲final對象,可是依然能夠往裏放入鍵值對繼承

Java提供常見不可變對象

Collections.unmodifiableXXX:Collection、List、Set、Map等。rem

@Slf4j
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));
    }
 
}

執行結果以下:get

 

發現執行結果爲拋出異常信息,不容許被修改。咱們能夠用這個方法來修飾不可變的集合對象。源碼

查看源碼的主要方法實現:

public class Collections {
    // Suppresses default constructor, ensuring non-instantiability.
        private Collections() {
        }
 
        private final Map<? extends K, ? extends V> m;
 
        UnmodifiableMap(Map<? extends K, ? extends V> m) {
            if (m==null)
                throw new NullPointerException();
            this.m = m;
        }
 
        ... ...
 
        public V put(K key, V value) {
            throw new UnsupportedOperationException();
        }
        public V remove(Object key) {
            throw new UnsupportedOperationException();
        }
        public void putAll(Map<? extends K, ? extends V> m) {
            throw new UnsupportedOperationException();
        }
        public void clear() {
            throw new UnsupportedOperationException();
        }
 
        ... ...
 
}

其實就是將put方法等直接拋出異常,防止修改。

其餘工具提供的不可變對象

Googel經常使用的工具包Guava一樣也提供了不少不可變對象的方法如 ImmutableXXX:Collection、List、Set、Map等。

相關文章
相關標籤/搜索