Java單例模式——靜態內部類實現
阿新 • • 發佈:2018-12-26
Singleton是眾多設計模式中最容易理解的一種,也是眾多設計模式中較為重要的一種設計模式。
Singleton模式實現的重點在於將建構函式私有化(private),並通過提供靜態公有函式(public synchronized static xxx getInstance)來獲取定義在類中的靜態私有成員(private static xxx instance),通過一個簡單的判斷靜態例項是否為空來控制這個類只能夠new一次,即控制了一個類只能有單個例項,一般的實現如下程式碼所示:
package com.study.dp.singleton; /** * 傳統方式實現單例模式 * @author CrazyPig * */ public class TraditionalSingletion { // 單例項 private static TraditionalSingletion instance; // 不讓new private TraditionalSingletion() { System.out.println("private TraditionalSingletion()"); } public synchronized static TraditionalSingletion getInstance() { System.out.println("TraditionalSingletion getInstance()"); if(instance == null) { System.out.println("instance = new TraditionalSingletion()"); instance = new TraditionalSingletion(); } return instance; } public static void main(String[] args) { TraditionalSingletion instance = TraditionalSingletion.getInstance(); System.out.println("========================================"); TraditionalSingletion instance01 = TraditionalSingletion.getInstance(); System.out.println("========================================"); TraditionalSingletion instance02 = TraditionalSingletion.getInstance(); } }
今天偶然在一篇文章中看到另外一種巧妙的做法,通過將這個單例項的引用變數定義在靜態內部類中,來實現單例,這樣可以做到不用if條件進行判斷,並且是多執行緒安全的(由jvm保證)。這個特殊的做法如下所示:
當第一次引用getInstance()方法的時候,訪問靜態內部類中的靜態成員變數,此時該內部類需要呼叫static程式碼塊(因為首次訪問該類)。而後再次訪問getInstance()方法會直接返回instace引用。這種做法相對於傳統做法更加巧妙。package com.study.dp.singleton; /** * 靜態內部類實現單例模式 * @author CrazyPig * */ public class SpecialSingleton { // 靜態內部類 private static class NestClass { private static SpecialSingleton instance; static { System.out.println("instance = new SingletonTest()"); instance = new SpecialSingleton(); } } // 不能直接new private SpecialSingleton() { System.out.println("private SingletonTest()"); } public static SpecialSingleton getInstance() { System.out.println("SingletonTest getInstance()"); return NestClass.instance; } public static void main(String[] args) { SpecialSingleton instance = SpecialSingleton.getInstance(); System.out.println("========================================"); SpecialSingleton instance01 = SpecialSingleton.getInstance(); System.out.println("========================================"); SpecialSingleton instance02 = SpecialSingleton.getInstance(); } }