JAva初期化と動的バインド

4652 ワード

初期化順序:
1、静的メンバーの初期化;
     まず、親クラスの静的メンバーの初期化(静的ドメイン値と静的文ブロックを含む、宣言順に初期化)と、子クラスメンバーの初期化です.ここは最上階のベースクラスまで遡りますね.
    静的メンバーの初期化は、クラスがロードされたときに発生し、コンストラクタが呼び出されたとは限らない.プログラムがクラスにアクセスしようとすると、このクラスがロードされます.
2、非静的メンバーの初期化;
3、コンストラクション関数を呼び出します.
注意2と3の順序は、親クラスの非静的メンバーの初期化-->親クラスコンストラクタ-->子クラスの非静的メンバーの初期化-->子クラスコンストラクタです.例は次のとおりです.
 
public class Father {



	private static int fa_static1 = printInit("static value in father!");

	private int fa_instance1 = printInit("instance value in father!");

	static

	{

		printInit("static block in father!");

	}

	private static int fa_static2 = printInit("another static value in father!");

	

	{

		printInit("common block in father!");

	}

	

	private int fa_instance2 = printInit("another instance value in father!");

	

	public Father(){

		System.out.println("default father constructor!");

	}

	public Father(int i){

		System.out.println("father constructor with parameter i = " + i);

	}

	

	protected static int printInit(String s){

		System.out.println(s);

		return 1;

	}



}

 
public class Son extends Father{



	private static int son_static1 = printInit("static value in son!");

	private int son_instance1 = printInit("instance value in son!");

	static

	{

		printInit("static block in son!");

	}

	private static int son_static2 = printInit("another static value in son!");

	

	{

		printInit("common block in son!");

	}

	private int son_instance2 = printInit("another instance value in son!");

	

	public Son(){

		System.out.println("default son constructor!");

	}

	

	public Son(int i){

		super(i);

		System.out.println("son constructor with parameter i = " + i);

	}

	

	public static void main(String[] args) {

		System.out.println("------test1-----------");

		Father.printInit("java");

		System.out.println("------test2-----------");

		Son s1 = new Son();

		System.out.println("------test3-----------");

		Son s2 = new Son(2);

	}

}
static value in father!

static block in father!

another static value in father!

static value in son!

static block in son!

another static value in son!

------test1-----------

java

------test2-----------

instance value in father!

common block in father!

another instance value in father!

default father constructor!

instance value in son!

common block in son!

another instance value in son!

default son constructor!

------test3-----------

instance value in father!

common block in father!

another instance value in father!

father constructor with parameter i = 2

instance value in son!

common block in son!

another instance value in son!

son constructor with parameter i = 2

解析:
test 1:Son.javaファイルを実行し、関数エントリmainを見つけます.これはSonの静的関数にアクセスしようとします.Sonクラスをロードする必要があります.ロード時に静的量を初期化します.ロード中に親Fatherが取得されるので、親の静的量を初期化します.2つのクラスの静的量の初期化が完了するとmainメソッドの実行が開始するtest 1が出力される.
出力結果から、静的メンバー変数と静的文ブロックの初期化順序は宣言順序と同じであることが分かった.
test 2:パラメトリックコンストラクタがないと、親クラスのコンストラクタが自動的に呼び出されます.インスタンスの初期化中にメンバー変数を初期化し、コンストラクタを呼び出します.
 
静的バインディングと動的バインディング:
コンセプト:
バインドとは、メソッドの呼び出しがメソッドが存在するクラス(メソッドボディ)に関連付けられていることを意味します.Javaでは、バインドは静的バインドと動的バインドに分けられます.あるいは、前期バインドと後期バインドと呼ばれます.
プログラムが実行前にバインドされると、コンパイラとリンクプログラムによって実現され、前期バインドと呼ばれます.C言語で呼び出す方法は1つだけで,前期バインドである.
実行時にオブジェクトのタイプに応じてバインドされます.後期バインドと呼ばれ、動的バインドまたは実行時バインドとも呼ばれます.
Javaではstaticメソッドとfinalメソッド(privateメソッドは自動的にfinalメソッドとみなされる)を除いて,他のすべてのメソッドは後期バインドである.
後期バインドはjavaで実現されるマルチステートの基礎である.
動的バインドのプロセス:仮想マシンがオブジェクトの実際のタイプを抽出するメソッドテーブル;仮想マシン検索方法の署名;メソッドを呼び出します.
【注意】バインドは、メソッドに対してのみ、ドメイン値には機能せず、どのクラスが宣言され、どのドメイン値が使用されますか.また、動的にバインドできるのは、親と子の両方のメソッドのみです.
public class Father {

	

	protected String name="    ";

	

	public String getName(){

		return name;

	}

}

public class Son extends Father{



	protected String name="    ";  

	protected String sonName = "        ";

	public String getSonName() {

		return sonName;

	}



	public String getName(){

		return name;

	}

	



	public static void main(String[] args) {

		Father fa = new Son();

		System.out.println("    :" + fa.name);

	

		//            ,         

		System.out.println("    :" + fa.getName());

//		System.out.println("    :" + fa.sonName);  //    

		//    ,father      。

//		System.out.println("    :" + fa.getSonName());  

	}

}