28

Singleton パターンを実装するために、次のコードを書きました。

public final class Test {
     static final class TestHolder {
         private static final Test INSTANCE = new Test();
     }     

     private Test() {}

     public static Test getInstance() {
         return TestHolder.INSTANCE;
     }
}

このファイルをコンパイルすると、Test.class と Test$TestHolder.class が生成されるはずですが、Test$1.class も生成されます。これは意味がありません。では、なぜ、どのようにこれが起こるのでしょうか?

4

1 に答える 1

29

クラスTestHolderは でプライベート コンストラクターを呼び出す必要がありますTest。しかし、これは非公開であり、実際には別のクラスから呼び出すことはできません。そのため、コンパイラはトリックを実行します。自分だけが知っている新しい非プライベート コンストラクタを追加します。Testそのコンストラクターは、この匿名クラスの (未使用の) インスタンスを受け取ります。この匿名クラスのTest$1存在は誰も知りません。次に、アクセス可能TestHolderコンストラクターのインスタンスを作成しTest$1て呼び出します (デフォルトで保護されています)。

javap -c Test(and javap -c Test\$1、 and ) を使用javap -c Test\$TestHolderしてコードを表示できます。実際、それはかなり賢いです!

于 2013-06-09T05:06:17.590 に答える