Java列舉:為什麼它是單例模式的最佳選擇?

不一樣的科技宅發表於2023-05-11

前言

  單例模式,是工作中比較常見的一種設計模式,通常有兩種實現方式,懶漢式和餓漢式。但是這兩種實現方式存在一些問題。懶漢式需要在多執行緒環境下使用同步鎖機制來保證只有一個例項被建立,這會影響程式的效能。而餓漢式在類載入時就建立例項,會導致程式在啟動時變慢,同時也無法延遲例項的建立,這可能會浪費系統資源。所以今天介紹一下,為什麼列舉是實現單例模式的最佳選擇。

示例程式碼

public enum Singleton {
    INSTANCE;

    // 新增需要的例項變數和方法
    private int count = 0;

    public void incrementCount() {
        count++;
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) {
        Singleton singleton = Singleton.INSTANCE;
        singleton.incrementCount();
        System.out.println(singleton.getCount()); // 輸出 1

        Singleton anotherSingleton = Singleton.INSTANCE;
        anotherSingleton.incrementCount();
        System.out.println(anotherSingleton.getCount()); // 輸出 2
        System.out.println(singleton.getCount()); // 輸出 2
    }
}

  在上面的示例中,Singleton 是一個列舉型別,其中宣告瞭一個列舉常量 INSTANCE,它是單例模式的唯一例項。

  該單例模式還可以擁有例項變數和方法,如上面的 count 例項變數和 incrementCount()、getCount() 方法。

  透過執行上面的程式碼,我們可以看到 singleton 和 anotherSingleton 是同一個例項,因為它們都是透過 Singleton.INSTANCE 獲取的,所以它們的計數器變數 count 是共享的,所以在 anotherSingleton 上呼叫 incrementCount() 方法後,singleton 上的 count 值也會被增加。

有哪些優點?

執行緒安全

  使用列舉實現單例模式是執行緒安全的。在多執行緒環境中,多個執行緒可以同時訪問單例物件,但是由於列舉的特殊性質,只有一個例項物件被建立,所以不會出現執行緒安全問題。

序列化安全

  使用列舉實現單例模式可以避免序列化和反序列化的問題。在 Java 中,當一個類被序列化並在另一個 JVM 中反序列化時,它會建立一個新的物件。如果使用列舉實現單例模式,則不需要擔心這個問題,因為列舉例項是在載入列舉型別時由 JVM 建立的,並且它們是全域性可訪問的,因此不會出現建立多個例項的情況。

防止反射攻擊

  使用列舉實現單例模式可以防止反射攻擊。在 Java 中,反射機制可以透過 Class 類來獲取物件的建構函式並建立新的物件。如果使用列舉實現單例模式,則可以避免這種攻擊,因為列舉型別的建構函式是私有的,不能透過反射來呼叫。

簡單明瞭可讀性強

  使用列舉實現單例模式可以使程式碼更加簡潔明瞭。列舉型別本身就是單例的,因此不需要編寫任何特殊的程式碼來實現單例模式。並且具有有意義的名稱和明確定義的值,這可以減少程式碼量和提高程式碼的可讀性。

總結

  首先,列舉例項是執行緒安全的,多執行緒環境下不會出現執行緒安全問題。其次,列舉例項由JVM建立的,可以避免序列化和反序列化的問題,並且它們是全域性可訪問的,也不會出現建立多個例項的情況。此外,列舉型別的建構函式是私有的,也可以防止反射攻擊。所以說java列舉是實現單例模式的最佳選擇。

結尾

  如果覺得對你有幫助,可以多多評論,多多點贊哦,也可以到我的主頁看看,說不定有你喜歡的文章,也可以隨手點個關注哦,謝謝。

  我是不一樣的科技宅,每天進步一點點,體驗不一樣的生活。我們下期見!

相關文章