オブジェクトの作成時にJVMが何をしてくれたか
2462 ワード
クラスがメモリにロードされていない場合は、クラスのロードを先に行います.
クラス内の静的コードブロックと静的属性の初期化値(コード順に実行)
オブジェクトを作成するときに何が起こりましたか?
非静的コードブロックと非静的属性の初期化値(コード順に実行)を呼び出し、構築方法を呼び出します.
次の例では、Bクラスがロードされず、BクラスがAを継承するBのオブジェクトを作成します.Aには2つの属性があり、1つの静的staticNumと1つの非静的numは、それぞれ静的方法staticMethodと非静的方法methodで与えられる.
実行結果:
A呼び出し静的方法静的属性初期化値A静的符号ブロックB呼び出し静的方法静的属性初期化値B静的符号ブロックA呼び出し一般方法属性初期化値A符号ブロックA構築方法B符号ブロックB構築方法
クラスロードフェーズの親と子、作成オブジェクトも親と子であることがわかります.
Class.forName()とClassLoader.getSystemClassLoader().loaderClass()この2種類のロード方式は違います.Class.forName()は静的コードブロックを実行し、静的属性の値を初期化しますが、classLoaderはクラスをハードディスクまたはネットワークからメモリにロードするだけで、接続も行わず、後の初期化も行わないので実行しません.これもJDBCドライバを取得する際にClassを使用する理由である.forName()の理由は、ソースコードが静的コードブロックで駆動オブジェクトを取得するためであり、以下のようになる.
クラス内の静的コードブロックと静的属性の初期化値(コード順に実行)
オブジェクトを作成するときに何が起こりましたか?
非静的コードブロックと非静的属性の初期化値(コード順に実行)を呼び出し、構築方法を呼び出します.
次の例では、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 {
}
}