大家先看下下面這段代碼的結果應該是多少?
public class ParentObjectInit {
public void test() {
}
public ParentObjectInit() {
test();
}
public static void main(String[] args) {
new ChildObjectInit();
}
}
class ChildObjectInit extends ParentObjectInit {
private int instanceValue = 20;
public void test() {
System.out.println("instance1 value is: " + instanceValue);
}
}
結果調試出來是20還是0呢?
*******************************************************************
(1)類中屬性缺省初始化和顯示初始化:
*******************************************************************
public class ParentObjectInit {
public void test() {
}
public ParentObjectInit() {
test();
}
public static void main(String[] args) {
//先調用父類ParentObjectInit 的構造器
new ChildObjectInit();
}
}
class ChildObjectInit extends ParentObjectInit {
//屬性顯示初始化在調用本類構造器之后
private int instanceValue = 20;
//進入ChildObjectInit類的構造器后,instanceValue值為20
public ChildObjectInit() {
System.out.println("instance1 value is: " + instanceValue);
}
// 在調用ChildObjectInit類構造器前打印
public void test() {
System.out.println("instance1 value is: " + instanceValue);
}
}
過程如下:
上面程序可以說明的是:直到調用完父類ParentObjectInit 的構造方法之后,接著才對其成員變量instanceValue 顯式的初始化操作,即將賦值20。
上面代碼中的private int instanceValue = 20;定義應看成兩部分:第一部分是定義變量,第二部分是給變量賦值。非static屬性定義(缺省初始化)位于父類ParentObjectInit 構造方法之前,非static屬性顯示賦值位于父類ParentObjectInit 構造方法之后。
在父類ParentObjectInit 的構造方法執行時,根據多態性,它會去調用子類中定義的test()方法,可是,這時候,子類中的成員變量還沒執行顯式初始化操作, 對于private int instanceValue = 20;定義,instanceValue 的值為默認的初始化值0,所以,這時候在test方法中打印出的值為0。
備注:
private int instanceValue = 20;改為static修飾,其結果就是20,因為static屬性在構造器調用之前就已經初始化了,并之后不會改變,屬于整個類共享。
*******************************************************************
(2)類中對象初始化流程:
*******************************************************************
class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
}
class Cupboard {
//非靜態初始化塊
{
Bowl b1 = new Bowl(1);
}
//靜態初始化塊
static{
Bowl b2 = new Bowl(2);
}
/**
* 非靜態實例屬性
*/
Bowl b3 = new Bowl(3);
/**
* 靜態實例屬性
*/
static Bowl b4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
}
void f3(int marker) {
System.out.println("f3(" + marker + ")");
}
/**
* 靜態實例屬性
*/
static Bowl b5 = new Bowl(5);
}
class StaticDataInit {
public static void main(String[] args) {
Cupboard t3 = new Cupboard();
t3.f3(1);
}
/**
* 和在main()里面用Cupboard t3 = new Cupboard();結果等價
*/
// static Cupboard t3 = new Cupboard();
}
運行結果為:
Bowl(2) 先調用static初始化塊
Bowl(4) 順序初始化static屬性b4和b5
Bowl(5) ...
Bowl(1) 調用非static初始化塊
Bowl(3) 調用非static實例屬性
Cupboard() 調用類Cupboard的構造器
f3(1) 對象t3調用f3方法
備注:如果將上面程序最后一句 static Cupboard t3 = new Cupboard();
注釋解開。
運行結果為:
//static Cupboard t3 = new Cupboard();初始化的結果
Bowl(2)
Bowl(4)
Bowl(5)
Bowl(1)
Bowl(3)
Cupboard()
//創建對象t3并調用方法f3的結果
Bowl(1)
Bowl(3)
Cupboard()
f3(1)
//說明static屬性和static塊只在對象第一次初始化或static屬性第一次初始化時賦值,以后不變
************************************************************************
形如:
public class A{
private int a = 100;
public A(){
//...
}
public static void main(String[] args){
new A();
}
}
//屬性a的缺省值為0,在調用構造器A()之前,屬性a的值是0。
//僅當調用到構造器A()后才將100顯示地賦給屬性a,之后再執行構造器中的邏輯。
總結:當一個類A中的對象a初始化時,依次先初始化其static初始化塊,static屬性,非static初始化塊(...)和非static屬性(缺省初始化)。然后再調用類A的構造器對A中的屬性進行顯示初始化。
posted on 2007-06-01 16:40
cheng 閱讀(1242)
評論(0) 編輯 收藏 所屬分類:
JBS