1

重複の可能性:
Java でのインスタンス変数の初期化
コンストラクター外の初期化はいつ呼び出されますか?

と の間に違いはA1ありA2ますか?

class A1 {
   B b = new B();
   A1() {
   }
}

//and  

class A2 {
   B b;
   A2() {
      b = new B();
   }
}

およびクラスB bをインスタンス化する場合、クラスがいつ構築を行うかを知りたいです。A1A2

4

3 に答える 3

1

それらの間に違いはありません。コンパイラは、インスタンス変数の初期化を、宣言するすべてのコンストラクター内の初期化ブロック内に自動的に配置します。

したがって、コンパイル後の最初の方法は次のようになります。

class A1 {
   B b;
   A1() {
      {
         b = new B();
      }
   }
}

ただし、2 番目の方法の方が読みやすいです。

Javaの本から一言で言えば - Chapter#3 :

ただし、フィールド宣言はメソッドの一部ではないため、ステートメントとして実行することはできません。代わりに、Java コンパイラはインスタンス フィールドの初期化コードを自動的に生成し、それをクラスのコンストラクタまたは複数のコンストラクタに配置します。初期化コードは、ソース コードに現れる順序でコンストラクターに挿入されます。つまり、フィールド初期化子は、その前に宣言されたフィールドの初期値を使用できます。

于 2012-10-20T09:47:06.360 に答える
1

コンストラクターは非静的データ メンバーを初期化するために使用され、データ メンバーの参照型であるため、両方のクラスで、およびB bのコンストラクターを呼び出すと、その構築が行われます。あなたが定義する場合A1A2B b

class A1{
  static B b=new B();
  A1(){
  }
}

その後、クラスのロード時にロードされます。コンパイラはクラスをロードし、クラスのロード時Bに のインスタンスを作成しますB。それ以外の場合、2 つの間に違いはありません。

于 2012-10-20T09:52:53.283 に答える
0

あなたが与えた例ではありません-違いはありません。どちらも、オブジェクトの作成時にBへの参照を開始します。

しかし、スタイルの面では、私は個人的にに傾いていA2ます。

A1クラスをもう少し解凍すると、次のようになります。

class A1 {
   B b;

   {
       b = new B();
   }

   A1() {
   }
}

上記の名前のないコードブロックは、初期化ブロックです。これは、オブジェクトが作成されるたびに実行されるコードのブロックです(呼び出されたコンストラクターに関係なく、コンストラクターの前に実行されます)。各コンストラクターの先頭にあるステートメント。これにより、に戻りA2ます。したがって、それらは同一です。

于 2012-10-20T09:43:38.297 に答える