親と子の2つのクラスがあります
public class Parent {
public Parent() {
System.out.println("Parent Constructor");
}
static {
System.out.println("Parent static block");
}
{
System.out.println("Parent initialisation block");
}
}
public class Child extends Parent {
{
System.out.println("Child initialisation block");
}
static {
System.out.println("Child static block");
}
public Child() {
System.out.println("Child Constructor");
}
public static void main(String[] args) {
new Child();
}
}
上記のコードの出力は次のようになります
Parent static block
Child static block
Parent initialization block
Parent Constructor
Child initialization block
Child Constructor
なぜJavaがこの順序でコードを実行するのですか?実行順序を決定するルールは何ですか?
プレイにはいくつかのルールがあります
super();
を暗黙的に呼び出します。初期化ブロックは、コンストラクターの呼び出し前でも機能するため、最初に呼び出されるのはこのためです。これで、親が作成され、プログラムは同じプロセスを実行する子クラスを作成し続けることができます。説明:
- loaded firstであるため、親の静的ブロックが最初に実行され、クラスがロードされるときに静的ブロックが呼び出されます。
私は視覚的に学習するので、ここに SSCCE としての順序の視覚的表現があります。
public class Example {
static {
step(1);
}
public static int step_1 = step(2);
public int step_6 = step(6);
public Example() {
step(8);
}
{
step(7);
}
// Just for demonstration purposes:
public static int step(int step) {
System.out.println("Step " + step);
return step;
}
}
public class ExampleSubclass extends Example {
{
step(9);
}
public static int step_3 = step(3);
public int step_10 = step(10);
static {
step(4);
}
public ExampleSubclass() {
step(11);
}
public static void main(String[] args) {
step(5);
new ExampleSubclass();
step(12);
}
}
これは印刷します:
Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
Step 7
Step 8
Step 9
Step 10
Step 11
Step 12
static
パーツの順序が重要であることに注意してください。 Example
のstatic
の順序とExampleSubclass
の順序の違いを振り返ります。
また、インスタンスの初期化ブロックは、順序に関係なく、コンストラクターの前に常に実行されることに注意してください。ただし、初期化ブロックとフィールド初期化子の間では順序は重要です。
最初に-単純なフローを表示するには、子クラスのみを実行します(extend節をコメントします)。
2番目- Javaの静的ブロックと初期化ブロックのどちらですか? に進み、そこに受け入れられた答えを読みます。
編集:
(コードでは、最初に親の静的ブロックが実行され、次に子クラスの静的ブロックが実行されます。)
子オブジェクトを作成するときのコードでは:
Javaの静的ブロックは、mainメソッドの前に実行されます。 JavaクラスでStaticブロックを宣言すると、クラスのロード時に実行されます。これは静的変数で初期化されます。主にJDBCで使用されます。 Javaの静的ブロックは、クラスがロードされるたびに実行されます。これは、静的初期化ブロックとも呼ばれます。 Javaの静的ブロックは、クラスがメモリにロードされるときに初期化されます。これは、JVMがバイトコードを読み取るタイミングを意味します。初期化は何でもかまいません。変数の初期化、またはそのクラスのすべてのオブジェクトで共有する必要のあるその他のものを指定できます。静的ブロックは、中括弧{}で囲まれた通常のコードブロックであり、静的キーワードが先行します。
そのため、静的ブロックが最初に実行されます。
インスタンス初期化ブロック:クラスのインスタンスが作成されるたびに実行されます。
そのため、クラスのインスタンスが作成されたときに実行される次の初期化ブロック。
その後、コンストラクタが実行されました
これは、認定の準備中に見つけたものです。
クラスを実行すると、最初の静的ブロック/静的変数の初期化が行われます。複数の静的ブロックが存在する場合、表示される順序で実行されますが、
その後、initブロック/インスタンス変数の初期化を実行します。複数のinitブロック/変数の初期化が存在する場合は、出現順に実行します。
その後、コンストラクターを調べます。
オブジェクトがフェーズをどのように進んでいるかを見ることができるビューを備えた、ステップごとのデバッガーでオブジェクト構築プロセスを開始することは非常に役立ちます。これは、より高い視点から視点をクリアするのに非常に役立ちました。 Eclipseは、デバッガーの機能へのステップでこれを支援します。
調査結果を共有したかっただけです。別のスレッドの回答の1つを読んだところ、静的フィールドは正しくない静的フィールドの前に最初に実行されます。静的フィールドと静的ブロックのどちらが先かによって異なります。以下のコードをご覧ください。物事を視野に入れようとします。
Mainメソッドに戻ります。
class TestLab {
static int method(String a) {
System.out.println("in static method of TestLab" + " Coming from " + a);
System.out.println("b is " + b);
return 6;
}
static int a = method("Line 11");
static int b = 7;
TestLab() {
System.out.println("Inside test lab constructor");
}
static {
System.out.println("In static block of TestLab");
}
}
public class Test1 {
public static void main(String[] args) {
System.out.println("inside main method of Test 1");
int a = TestLab.method("Line 26");
}
// static Test ref=new Test();
Test1() {
System.out.println("Default Constructor of Test1");
}
{
System.out.println("In instance block of Test1");
}
static int d = TestLab.method("Line 37");
static int e = methodOfTest1();
static {
System.out.println("In Static Block of Test1");
}
static int methodOfTest1() {
System.out.println("inside static method:mehtodOfTest1()");
return 3;
}
}
出力は次のとおりです。
in static method of TestLab Coming from Line 11
b is 0
In static block of TestLab
in static method of TestLab Coming from Line 37
b is 7
inside static method:mehtodOfTest1()
In Static Block of Test1
inside main method of Test 1
in static method of TestLab Coming from Line 26
b is 7
制御フローは
static block-> Initialization block->最後にConstructor。
静的ブロック->この静的ブロックは、コントロールがクラスに来たときに一度だけ実行されます。(JVM Load this class)
初期化ブロック->この初期化ブロックは、クラス用に作成された新しいオブジェクトのたびに実行されます(コンストラクターの2番目のステートメントから実行され、コンストラクターステートメントの後に実行されます-最初のステートメントを記憶しますコンストラクタのSuper()/ this())
コンストラクタ->これは、新しいオブジェクトが作成されるたびに取得されます。
1.Static initブロックは、クラスのロード時に1つだけ実行されます。 2.Initブロックは、クラスのオブジェクトを作成する前に毎回実行されます。
クラスがJVMにロードされると、静的ブロックが実行されます。初期化ブロックは、オブジェクトが作成されるコンストラクタにコピーされ、オブジェクトの作成前に実行されます。