コンストラクターと比較して、クラスの最上位の変数はいつ初期化されますか?
申し訳ありませんが、これは私が意味したことです:
public class aClass {
private int num;
public aClass {...}
デフォルト値(null
オブジェクトフィールドの場合0
など、プリミティブフィールドの場合)は、発行されたバイトコードに関する限り、技術的に明示的に割り当てられることはありません。(これは、初期化子/コンストラクターコードが実行される前に、オブジェクトのインスタンス化中に「内部的に」実行されます。)
インスタンスフィールドの明示的な初期化コードは、コンパイラによるクラス内のスーパークラスコンストラクター呼び出し(存在する場合)の後、すべてのコンストラクターの開始時に「コピー」されます。コードサンプル:
class Foo {
int bar = 123;
public Foo() {
// ...
}
public Foo(int bar) {
this.bar = bar;
// ...
}
}
次と同等のバイトコードにコンパイルされます。
class Foo {
int bar;
public Foo() {
this.bar = 123;
// ...
}
public Foo(int bar) {
this.bar = 123;
this.bar = bar;
// ...
}
}
イニシャライザブロックについても同じことが言えます。これは、これらの変数が通常のコンストラクターコードが実行される前に初期化されることを意味します。
値で定義されたメンバーは、他のメンバーと同様に、コンストラクターで初期化されます。しかし、それはあなたが書いたコンストラクターではありません。Javaは、メンバーの初期化子と初期化子ブロックをその先頭に挿入することにより、各コンストラクターをバックグラウンドで変更します。一時的に表示したい場合は、コンストラクターの直前でメンバーが初期化されていると見なすことができます。
事実上、コンストラクターが呼び出される前にそれらが初期化されていると見なすことができます。だからあなたが持っているなら:
class Dog {
private String voice = "woof";
public Dog() {
System.out.println(voice);
}
}
ではなく、コンソールに「woof」が正常に出力されnull
ます。