【Javaノート】クラスの初期化手順


この文章を読む前に、筆者の静的コードブロックとコードブロックを構築する文章を読んでください.
    筆者はJavaを勉強しているうちに、いつも一連の疑問を抱いている.この学習方法はよい.何かを学ぶには、受け身に受け入れるだけでなく、考えるべきだ.最初にJavaを勉強したとき、筆者は仮想マシンがどのような仕事をしたのか不思議に思った.仮想マシンはどのようにメモリを割り当てますか?仮想マシンはどのようにバイトコードを実行しますか?もちろん、これらの問題を理解するには、「Java仮想マシンを深く理解する」を読む必要があります.
    クラスを勉強するとき、Javaのクラスはどのようにメモリの中で動作していますか?Javaのオブジェクトはどのように生成されますか?Javaのクラスはどのようにしてメモリにロードされますか?プログラムを実行すると、すべてのクラスをメモリにロードしますか?そうしないとどうなりますか?このシリーズの問題は、筆者を困惑させている.一つの問題が分からなかったら、筆者はそれをノートに整理して、みんなが読むようにします.
    インスタンスコードをここに貼り付けます.
package lin;
import static java.lang.System.out;
public class Lin {

    { //       
        System.out.println("Normal block start.");
        t1 = new Test(1);
        t2 = new Test(2);
        t3 = new Test(3);
        System.out.println("Normal block end.");
    }

    static  //       
    {
        System.out.println("Static block start.");
        t = new Test(0);
        System.out.println("Static block end.");
    }
    public static void main(String args[]) {

        System.out.println("main() start.");
        new Lin();
        new Lin();
        System.out.println("main() end.");

    }
    public Lin() {
 
        System.out.println("Lin()");

    }
    public Test t1;
    public Test t2;
    public Test t3;
    public static Test t;

}
class Test {

    public int a = 0;
    Test() {

        System.out.println("Test");

    }
    Test(int a) {

        this.a = a;
        System.out.println("Test(" + a + ")");

    }

}
<span style="font-family:SimSun;">//    
/*
Static block start.
Test(0)
Static block end.

main() start.

Normal block start.
Test(1)
Test(2)
Test(3)
Normal block end.
Lin()

Normal block start.
Test(1)
Test(2)
Test(3)
Normal block end.
Lin()

main() end.
*/
</span>
   
    実行結果:クラスの静的コードブロック-mainメソッド- 構築コードブロック- 構築方法- 構築コードブロック- 構造方法.2つのオブジェクトをインスタンス化したが、静的コードブロックは1回しか実行されなかった.
    次に、Java仮想マシンがクラスをロードする方法と、クラスの初期化順序について説明します.車を持つには、図面が必要です.そのため、まずクラスがあってこそ、オブジェクトと付き合うことができます.
    1.クラスのロード.    1つのプログラムには多くの種類があり、大きなプロジェクトには何千もの種類があります.プログラムを実行するとき、これらのちゃんぽんを全部メモリに捨てますか?答えは決まっているに違いない.これらのクラスには、主関数エントリが存在するクラスである主クラスが常に存在します.プログラムを実行するときは、まずこのクラスをメモリにロードします.なぜオブジェクトではなくクラスなのかと聞かれる.mainメソッドにpublicとstaticが修飾されていることに気づいたことはありますか?はい、mianメソッドは実際にクラスに属しており、クラスをインスタンス化するオブジェクトを必要とせずに直接呼び出すことができます.見知らぬクラスを呼び出すには、Java仮想マシンがCLASSSPATHで指定したパスでこのクラスを検索します.もちろんクラスはバッグの中にあります.では、どのようにロードしますか?いくつかのステップがあります.    マウント:クラスまたはインタフェースのバイナリデータの検索とインポート;    リンク:次の検証、準備、および解析ステップを実行します.ここで、解析ステップは選択できます.    検証:インポートクラスまたはインタフェースのバイナリデータの正確性を確認します.    準備:クラスの静的変数にストレージスペースを割り当てて初期化します.    解析:シンボル参照を直接参照に変換します.    ≪初期化|Initialization|emdw≫:クラスの静的変数の初期化Javaコードと静的Javaコードブロックをアクティブにします(初期化クラスのプロパティは静的コードブロックの一般的な用途ですが、一度しか使用できません).
    注意:Javaでは、クラス・ローダはJava仮想マシンにクラスをロードします.ロード、リンク、初期化の3つのステップを経て完了します.リンクは検証、準備、解析の3つのステップに分けられます.解析のほか、他のステップは厳格に順序に従って完了します.
    クラスをロードすると、クラス内の静的メソッドがメモリ(スタック)にロードされます.スタックに静的ドメインを保存しながら初期化するための空間を割り当てます.ドメインがクラスのオブジェクトである場合は、上記の手順に従ってそのクラスをメモリにロードします.クラスの静的ドメインをどのように初期化しますか?それは前述した静的コードブロックです.これは初期化クラスで最初に実行されます.
    2. オブジェクトを作成します.
    クラスをロードすると、クラスの設計図面があり、オブジェクトをインスタンス化できます.コンストラクタ呼び出しの前に作成したワーク仮想マシンについて説明しました.だから、まずこれらの仕事を完成しなければなりません.それは構築コードブロックを実行することです.これらの作業が完了すると、クラスのコンストラクタが呼び出され、クライアント・プログラマがオブジェクトのドメインを初期化します.
    以上:クラスはメモリにロードされ、クラスの静的ドメインが初期化されます.次にクラスのオブジェクトをインスタンス化し、オブジェクトドメインを初期化します.すなわちstatic修飾付きドメインが先に初期化される.彼らの順番は、静的コードブロック-> コードブロックの作成-> コンストラクタ.
    もちろん、クラスがスーパークラスを継承している場合もあります.では、このような状況では、初期化の順序はどのようなものなのでしょうか.父がいないのにどこから来た子がいるのか想像できます.だから順番は自然にこうです.
    1.  親静的メンバーと静的初期化ブロックは、コードに表示される順序で順次実行されます.    2.  サブクラスの静的メンバーと静的初期化ブロックは、コードに表示される順序で順次実行されます.    3.  親インスタンスメンバーとインスタンス初期化ブロックは、コードに表示される順序で順次実行されます.    4.  親の構築方法    5.  サブクラスインスタンスメンバーとインスタンス初期化ブロックは、コードに表示される順序で順次実行されます.    6.  サブクラス構築方法
    読者は自分で小さなプログラムを書いて結果を試してみることができます.