オブジェクトの作成時にJVMが何をしてくれたか

2462 ワード

クラスがメモリにロードされていない場合は、クラスのロードを先に行います.
クラス内の静的コードブロックと静的属性の初期化値(コード順に実行)
オブジェクトを作成するときに何が起こりましたか?
非静的コードブロックと非静的属性の初期化値(コード順に実行)を呼び出し、構築方法を呼び出します.
次の例では、Bクラスがロードされず、BクラスがAを継承するBのオブジェクトを作成します.Aには2つの属性があり、1つの静的staticNumと1つの非静的numは、それぞれ静的方法staticMethodと非静的方法methodで与えられる.
package stringTest;

/**
 * writer: holien
 * Time: 2017-11-25 10:09
 * Intent:          
 */
public class LoadingOrder {
    public static void main(String[] args) throws Exception {
        B b = new B();
//        Class.forName("stringTest.B");  //                  
//        ClassLoader.getSystemClassLoader().loadClass("stringTest.B");  //    ,    
    }
}

class A {
    //                (     )
    static int staticNum = staticMethod();

    static {
        System.out.println("A     ");
    }

    //                     (      )
    int num = method();

    {
        System.out.println("A   ");
    }

    //          
    A() {
        System.out.println("A    ");
    }

    static int staticMethod() {
        System.out.println("A               ");
        return 5;
    }

    int method() {
        System.out.println("A             ");
        return 5;
    }

}

class B extends A {
    static int num2 = staticMethod1();

    static {
        System.out.println("B     ");
    }

    static int staticMethod1() {
        System.out.println("B               ");
        return 5;
    }

    {
        System.out.println("B   ");
    }

    B() {
        System.out.println("B    ");
    }
}

実行結果:
A呼び出し静的方法静的属性初期化値A静的符号ブロックB呼び出し静的方法静的属性初期化値B静的符号ブロックA呼び出し一般方法属性初期化値A符号ブロックA構築方法B符号ブロックB構築方法
クラスロードフェーズの親と子、作成オブジェクトも親と子であることがわかります.
Class.forName()とClassLoader.getSystemClassLoader().loaderClass()この2種類のロード方式は違います.Class.forName()は静的コードブロックを実行し、静的属性の値を初期化しますが、classLoaderはクラスをハードディスクまたはネットワークからメモリにロードするだけで、接続も行わず、後の初期化も行わないので実行しません.これもJDBCドライバを取得する際にClassを使用する理由である.forName()の理由は、ソースコードが静的コードブロックで駆動オブジェクトを取得するためであり、以下のようになる.
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    static {
        try {
            // DriverManager     
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }

    public Driver() throws SQLException {
    }
}