靜態內部類與非靜態內部類之間存在一個最大的區別,我們知道非靜態內部類在編譯完成之後會隱含地保存着一個引用,該引用是指向創建它的外圍類,但是靜態內部類卻沒有。沒有這個引用就意味着:
- 它的創建是不需要依賴外圍類的創建。
- 它不能使用任何外圍類的非static成員變量和方法。
Example(靜態內部類實現單例模式)
public class Singleton {
// 聲明爲 private 避免調用默認構造方法創建對象
private Singleton() {
}
// 聲明爲 private 表明靜態內部該類只能在該 Singleton 類中被訪問
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getUniqueInstance() {
return SingletonHolder.INSTANCE;
}
}
當 Singleton 類加載時,靜態內部類 SingletonHolder 沒有被加載進內存。只有當調用 getUniqueInstance() 方法從而觸發 SingletonHolder.INSTANCE 時 SingletonHolder 纔會被加載,此時初始化 INSTANCE 實例,並且 JVM 能確保 INSTANCE 只被實例化一次。
這種方式不僅具有延遲初始化的好處,而且由 JVM 提供了對線程安全的支持。