1. 程式人生 > >載入一個類時,其內部類是否同時被載入?靜態內部類單例模式

載入一個類時,其內部類是否同時被載入?靜態內部類單例模式

載入一個類時,其內部類是否同時被載入?下面我們做一個實驗來看一下。 
Java程式碼  
  1. public class Outer {  
  2.     static {  
  3.         System.out.println("load outer class...");  
  4.     }  
  5.     //靜態內部類  
  6.     static class StaticInner {  
  7.         static {  
  8.             System.out.println("load static inner class...");  
  9.         }  
  10.         static
     void staticInnerMethod() {  
  11.             System.out.println("static inner method...");  
  12.         }  
  13.     }  
  14.     public static void main(String[] args) {  
  15.         Outer outer = new Outer();      //此刻其內部類是否也會被載入?  
  16.          System.out.println("===========分割線===========");  
  17.         Outer.StaticInner.staticInnerMethod();      //呼叫內部類的靜態方法
      
  18.     }  
  19. }  

執行結果: 
load outer class... 
==========分割線========== 
load static inner class... 
static inner method... 

    呼叫構造方法時,外部類Outer被載入,但這時其靜態內部類StaticInner卻未被載入。直到呼叫該內部類的靜態方法(在分割線以下),StaticInner才被載入。可以做類似的實驗驗證非靜態內部類的情況。 
結論:載入一個類時,其內部類不會同時被載入。一個類被載入,當且僅當其某個靜態成員(靜態域、構造器、靜態方法等)被呼叫時發生。

    根據內部類不會在其外部類被載入的同時被載入的事實,我們可以引申出單例模式的一種實現方式: 

Java程式碼  
  1. public class Singleton {  
  2.     private Singleton() {}  
  3.     static class SingletonHolder {  
  4.         private static final Singleton instance = new Singleton();  
  5.     }  
  6.     public static Singleton getInstance() {  
  7.         return SingletonHolder.instance;  
  8.     }  
  9. }  

    該實現方式比較簡單,而且既實現了由前述事實所保證的惰性初始化(Lazy-Initialazation),又由JVM保證了多執行緒併發訪問的正確性。