9

重複の可能性:
Java での二重ブレースの初期化とは?

いくつかのレガシーコードを見ていると、非常に紛らわしいものに出くわしました:

 public class A{
      public A(){ 
          //constructor
      }
      public void foo(){
            //implementation ommitted
      }
 }

 public class B{
      public void bar(){
           A a = new A(){ 
                { foo(); }
           }
      }
 }

{ foo() }デバッグ モードでコードを実行すると、コンストラクターが呼び出された後に匿名ブロックが呼び出されることがわかりましたA()。上記の機能は、次のこととどのように機能的に異なりますか。

 public void bar(){
       A a = new A();
       a.foo();
 }

? 私はそれらが機能的に同等であると思います.後者の方法はコードを書くためのより良い/よりクリーンな方法だと思います.

4

3 に答える 3

8
 { foo(); }

インスタンス初期化子と呼ばれます。

なぜ?

Javaチュートリアルに従って

Java コンパイラは、イニシャライザ ブロックをすべてのコンストラクタにコピーします。したがって、このアプローチを使用して、複数のコンストラクター間でコードのブロックを共有できます。

于 2013-01-08T20:44:39.320 に答える
4

「インスタンス初期化子は、(1) 初期化子コードが例外をキャッチする必要がある場合、または (2) インスタンス変数初期化子では表現できない手の込んだ計算を実行する必要がある場合に、インスタンス変数初期化子に代わる便利な方法です。もちろん、常にそのような記述を行うこともできます。コンストラクター内のコード. しかし、複数のコンストラクターを持つクラスでは、各コンストラクターでコードを繰り返す必要があります. インスタンス初期化子を使用すると、コードを一度書くだけで、どのコンストラクターを使用して作成しても実行されます.オブジェクト. インスタンス初期化子は、コンストラクターをまったく宣言できない匿名の内部クラスでも役立ちます。」ソース

これは、この回答にも引用されています。

于 2013-01-08T20:47:48.287 に答える
2

オブジェクトのランタイム クラスが ( を呼び出すことによって) アクセスされ、何らかの理由 (たとえば、スーパー タイプ トークンとして機能するためgetClass()) と異なる必要がある場合を除き、実際には違いはなく、単に構築後に呼び出すことは実際にはより一般的なイディオム。Afoo()

于 2013-01-08T20:49:37.477 に答える