これが私のコードです:
public class Test
{
static
{
main(null);
}
public static void main(String [] args)
{
System.out.println("done");
}
}
次の出力が得られます。
done
done
誰かが私にこの理由を説明してもらえますか?
その理由は、main
が 2 回呼び出されるためです。
これを修正する方法は?明示的に呼び出さないか、自動的に呼び出されないように名前を変更してください。
何が珍しいと思いますか?static
ブロックは、クラスがロードされるときに1回実行されます(メソッドを実行する前にロードする必要があります。main
その後、main
メソッド自体が実行されます。
この変更されたバージョンをチェックしてください:
public class Test {
static {
main(new String[]{"[done static]"});
}
public static void main(String[] args) {
System.out.println(args.length > 0 ? args[0] : "[done]");
}
}
それは印刷します:
[done static]
[done]
なぜなら
static { ... }
部分は、クラスTest
が JVM 内にロードされるときに呼び出されます (一種の静的コンストラクターです)。main
実行の開始時にメソッドが呼び出されている間。メインは、jarをロードするときに、仮想マシンによって自動的に呼び出されます。したがって、これは最初の「完了」であり、Javaプログラムの通常のエントリポイントです。
2番目の「Done」は、静的クラス初期化子で明示的に呼び出すために書き込まれます。「Test」クラスに追加した「static」セクションは、クラスが仮想マシンのクラスローダーによってロードされるとすぐに呼び出されます。
エントリポイントが呼び出される前にクラスをロードする必要があるため、静的初期化子からのものは、エントリポイントMainが呼び出される前に呼び出す必要があります。
を呼び出す前Test.main
に、JVMはTest
静的初期化子を実行してクラスを初期化する必要があります。この呼び出しは、の最初の呼び出しを担当しますmain()
。初期化が完了すると、JVMがmain()
再度呼び出し、最終的に表示される出力を生成します。
Main は JVM によって自動的に呼び出されます。static セクションで呼び出す必要はありません。
public class Test
{
public static void main(String [] args)
{
System.out.println("done");
}
}
上記のコードは、本来あるべきものです。
クラスの静的ブロックは、クラスが最初にロードされるときに呼び出されます。それが最初にできたことです。2 つ目は、プログラムを実行していて、メイン メソッドが呼び出されるためです。