---------------------- ASP.Net+Android+IOS開發、.Net教育訓練、期待與您交流! ----------------------
構造函數的初始化
如果在類當中,沒有寫構造函數,在主函數建立該類對象的時候,java編譯器會自動加上一個空參數和空方法體的構造函數。
但是有一點要注意的是,構造函數有下面這種
Person(int age)
{
this.age = age;
}
Person(String name)
{
this.name = name;
}
Person(String name,int age)
{
this.name = name;
this.age = age;
}
注意:如果類中沒有定義一個無參構造,但是類中是存在有參的構造函數并且在建立對象的時候用以下方式建立
Person p1 = new Person();
這樣會導緻編譯不通過,因為類中并不存在一個無參構造,但是類中并不是沒有構造函數的,是以編譯器此時不會自動再加上一個無參的構造函數
構造代碼塊的要點
構造代碼塊
構造代碼塊是先于構造函數執行的,每建立一個對象都要執行一遍
作用:構造代碼塊是給所有對象進行統一的初始化
而構造函數是給特定的調用的對象初始化
問題是:既然兩者都是一建立對象就執行,那為什麼要單獨寫一個構造代碼塊而不都寫進構造函數,我是這樣了解的
其實也可以了解成,當一個類當中有多個構造函數的時候,那麼如果沒有構造代碼塊,每個構造函數裡面同會有同樣功能的一段代碼,那麼java這個語言就是面向對象的,重複性的東西可以提取出來,單獨作為一個代碼塊,提高代碼的複用性和健壯性,也就有了把構造函數裡的東西單獨封裝成構造代碼塊
靜态代碼塊的特點:随着類的加載而執行,而且隻執行一次,并且優先于主函數優先執行,用于給類進行初始化的
構造代碼塊給所有對象初始化的
構造函數是給特定對象初始化的
三者的優先級為:靜态代碼塊 >構造代碼塊 >構造函數
對象的初始化的時候,類的内部執行順序問題
1. 運作以下代碼片段,輸出結果是?()
class X {
Yb = new Y();
X(){
System.out.print("X");
}
}
class Y {
Y(){
System.out.print("Y");
}
}
public class Z extends X {
Yy = new Y();
Z(){
System.out.print("Z");
}
publicstatic void main(String[] args) {
new Z();
}
}
子類對象的執行個體化過程:
建立對象的執行流程:
1 new通過構造器來開辟記憶體空間,其中包含了父類子對象的空間;
2 new把這個剛剛建立的對象引用給出構造器,new的工作完成了;
3 構造器(非委派)會先去調用父類構造器;
4 父類構造器先執行顯示初始化語句;
5 父類構造器再執行自己的方法體内容,父類構造器工作結束了;
6 回到子類構造器,開始執行顯示初始化語句;
7 再執行構造器的方法體内容;
8 傳回這個引用,結束。
當父類,和子類有Static時,先初始化Static,再初始化子類的Static,再初始化父類的其他成員變量->父類構造方法->子類其他成員變量->子類的構造方法。
父類上層還有父類時,總是先執行最頂層父類的Static-->派生類Static-->派生類Static-->.......-->子類Static-->頂層父類的其他成員變量-->父類構造方法--> 派生類的其他成員變量--> 派生類構造方法--> ...............-->子類其他成員變量-->子類構造方法(摘自傲鴿的文章)
我的了解:其實繼承父類,在執行個體化子類的時候,調用父類構造方法其實還隐含了一個資訊,就是會初始化父類的變量。
這樣說會更好:執行個體化子類,先執行個體化父類(而不單單說隻調用父類構造方法)
是以我這個代碼的正确執行順序應該是
new Z();--->先執行個體化父類(執行Y b = new Y();輸出:Y,然後輸出X),然後回到X類中,執行Y y = new Y();輸出Y,最後再執行Z類的自身的構造函數,輸出Z
是以最後的結果YXYZ就是這麼來的
---------------------- ASP.Net+Android+IOS開發、.Net教育訓練、期待與您交流! ----------------------
詳細請檢視:http://edu.csdn.net