クラスをロードすると、その内部クラスは同時にロードされますか?単一例モードの別の実装方式を示す


クラスをロードすると、その内部クラスは同時にロードされますか?次に実験をしてみましょう.

public class Outer {
    static {
        System.out.println("load outer class...");
    }
    
    // 
    static class StaticInner {
        static {
            System.out.println("load static inner class...");
        }
        
        static void staticInnerMethod() {
            System.out.println("static inner method...");
        }
    }
        
    public static void main(String[] args) {
        Outer outer = new Outer();      // ?
         System.out.println("=========== ===========");
        Outer.StaticInner.staticInnerMethod();      // 
    }
}

実行結果:
load outer class...
===========分割線========
load static inner class...
static inner method...
構築メソッドを呼び出すと、外部クラスOuterがロードされますが、静的内部クラスStaticInnerはロードされません.内部クラスの静的メソッド(分割線以下)が呼び出されるまで、StaticInnerはロードされません.非静的内部クラスの場合を同様の実験で検証することができる.
   
結論:クラスをロードすると、内部クラスは同時にロードされません.1つのクラスがロードされ、静的メンバー(静的ドメイン、コンストラクタ、静的メソッドなど)が呼び出された場合にのみ発生します.
内部クラスが外部クラスにロードされないという事実に基づいて、単一のパターンの実装方法を説明することができる.

public class Singleton {
    private Singleton() {}
    
    static class SingletonHolder {
        private static final Singleton instance = new Singleton();
    }
    
    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}

この実装は比較的簡単であり,前述の事実によって保証された不活性初期化(Lazy−initialazation)を実現するとともに,JVMによってマルチスレッド同時アクセスの正確性を保証する.