あなたはそれを知る必要があります
- コンストラクターの最初の命令は、その親クラスのコンストラクターを呼び出す
super(params)
か、デフォルトのコンストラクターを使用する場合ですsuper()
。デフォルトのコンストラクタの場合、明示的に記述する必要はありません。
super(...)
初期化ブロック内のコードは、呼び出しの直後にすべてのコンストラクターに移動されます
- 静的ブロックは、クラスが初期化されるときに実行されます。これは、JVM によって (その親クラスと共に) 完全にロードされた後に実行されます。
したがって、クラスはこれに似たクラスにコンパイルされます。
public class Parent {
static {
System.out.println("Parent static block");
}
public Parent() {
super();
{
System.out.println("Parent initializer block");
}
System.out.println("Parent constructor");
}
}
public class Son extends Parent {
static {
System.out.println("Son static block");
}
public Son() {
super();
{
System.out.println("Son initializer block");
}
System.out.println("Son constructor");
}
public static void main(String[] args) {
new Son();
}
}
クラス JVMmain
からメソッドを実行できるようにするには、このクラス (およびそれが拡張するクラス) のコードをロードする必要があります。クラスが完全にロードされた後、JVMは静的ブロックの実行を含む静的コンテンツを初期化します (はい、1 つのクラスに複数の静的ブロックが存在する可能性があります)。クラスを完全にロードするには、JVM はその親クラスの詳細を知る必要があるため、その前にクラスを完全にロードします。つまり、クラス内の静的ブロックの前に静的ブロックも実行します。Son
Son
Parent
Son
Son
したがって、出力は次のようになります。
Parent static block
Son static block
メソッドで、コードが次のように見えるクラスコンストラクターをmain
呼び出していますSon
new Son()
super();
{
System.out.println("Son initializer block");
}
System.out.println("Son constructor");
クラスコンストラクターをsuper()
参照しているため、Parent
super();// this will invoke Object constructor since Parent
// doesn't extend anything (which means it extends Object class)
{
System.out.println("Parent initializer block");
}
System.out.println("Parent constructor");
結果としてあなたは見るでしょう
Parent initializer block
Parent constructor
このハンドルは次のようにParent#constructor()
実行されるので、次に生成されるsuper()
Son コンストラクターからのコードが表示されます。super()
Son initializer block
Son constructor
Son
コンストラクターやメソッドを使用する前でもクラスがロードされることを確認するには、コンストラクターのようなmain
ものを使用する前に何かを出力するだけですSon
System.out.println("ABC // before new Son()");
new Son();
その結果、
Parent static block
Son static block
ABC // before new Son()
Parent initializer block
Parent constructor
Son initializer block
Son constructor