と の間に違いはA1
ありA2
ますか?
class A1 {
B b = new B();
A1() {
}
}
//and
class A2 {
B b;
A2() {
b = new B();
}
}
およびクラスB b
をインスタンス化する場合、クラスがいつ構築を行うかを知りたいです。A1
A2
と の間に違いはA1
ありA2
ますか?
class A1 {
B b = new B();
A1() {
}
}
//and
class A2 {
B b;
A2() {
b = new B();
}
}
およびクラスB b
をインスタンス化する場合、クラスがいつ構築を行うかを知りたいです。A1
A2
それらの間に違いはありません。コンパイラは、インスタンス変数の初期化を、宣言するすべてのコンストラクター内の初期化ブロック内に自動的に配置します。
したがって、コンパイル後の最初の方法は次のようになります。
class A1 {
B b;
A1() {
{
b = new B();
}
}
}
ただし、2 番目の方法の方が読みやすいです。
Javaの本から一言で言えば - Chapter#3 :
ただし、フィールド宣言はメソッドの一部ではないため、ステートメントとして実行することはできません。代わりに、Java コンパイラはインスタンス フィールドの初期化コードを自動的に生成し、それをクラスのコンストラクタまたは複数のコンストラクタに配置します。初期化コードは、ソース コードに現れる順序でコンストラクターに挿入されます。つまり、フィールド初期化子は、その前に宣言されたフィールドの初期値を使用できます。
コンストラクターは非静的データ メンバーを初期化するために使用され、データ メンバーの参照型であるため、両方のクラスで、およびB b
のコンストラクターを呼び出すと、その構築が行われます。あなたが定義する場合A1
A2
B b
class A1{
static B b=new B();
A1(){
}
}
その後、クラスのロード時にロードされます。コンパイラはクラスをロードし、クラスのロード時B
に のインスタンスを作成しますB
。それ以外の場合、2 つの間に違いはありません。
あなたが与えた例ではありません-違いはありません。どちらも、オブジェクトの作成時にBへの参照を開始します。
しかし、スタイルの面では、私は個人的にに傾いていA2
ます。
A1
クラスをもう少し解凍すると、次のようになります。
class A1 {
B b;
{
b = new B();
}
A1() {
}
}
上記の名前のないコードブロックは、初期化ブロックです。これは、オブジェクトが作成されるたびに実行されるコードのブロックです(呼び出されたコンストラクターに関係なく、コンストラクターの前に実行されます)。各コンストラクターの先頭にあるステートメント。これにより、に戻りA2
ます。したがって、それらは同一です。