六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

構造方法的初始化順序(翻譯:Cherami)

[摘要]構造方法的初始化順序翻譯:Cheramiemail:cherami@163.net原文: http://java.sun.com/jdc/TechTips/2000/tt1205.html 想像一下你正在用java寫程序,并且用下面的代碼初始化類 A 和 B 的對象:class A int a =...
構造方法的初始化順序
翻譯:Cherami

email:cherami@163.net

原文: http://java.sun.com/jdc/TechTips/2000/tt1205.html



想像一下你正在用java寫程序,并且用下面的代碼初始化類 A 和 B 的對象:

class A {

int a = f();

int f() {

return 1;

}



class B extends A {

int b = a;

int f() {

return 2;

}

}

public class CtorDemo1 {

public static void main(String args[]) {

B bobj = new B();

System.out.println(bobj.b);

}

}



現在,好像很明顯的當初始化完成后,bobj.b的值將是1。畢竟,類B中的b 的值是用類A中的a的值初始化的,而a 是用f 的值初始化的,而它的值為1,對嗎?

實際上, bobj.b 的值是2,要知道為什么需要知道對象初始化的問題。

當一個對象被創建時,初始化是以下面的順序完成的:

1. 設置成員的值為缺省的初始值 (0, false, null)

2. 調用對象的構造方法 (但是還沒有執行構造方法體)

3. 調用父類的構造方法

4. 使用初始化程序和初始塊初始化成員

5. 執行構造方法體



看看在實際中是如何一步一步完成的,看看下面的例子:

class A {

A() {

System.out.println("A.A called");

}

}



class B extends A {

int i = f();

int j;



{

j = 37;

System.out.println("initialization block executed");

}



B() {

System.out.println("B.B called");

}



int f() {

System.out.println("B.f called");

return 47;

}

}



public class CtorDemo2 {

public static void main(String args[]) {

B bobj = new B();

}

}



程序的輸出是:



A.A called

B.f called

initialization block executed

B.B called



B 的構造方法被調用,但是最先做的事情是隱含的調用父類的構造方法。父類必須自己負責初始化它自己的狀態而不是讓子類來做。

然后B對象的成員被初始化,這包含一個對B.f 的調用和包圍在{}中的初始塊的執行。最后B的構造方法體被執行。

你可能會問“什么是對父類的構造方法的隱含調用”。這意味著如果你的構造方法的第一行不是下面內容之一:



 super();



 super(args);



 this();



 this(args);



則有下面的調用:



 super();



提供給構造方法的第一行。



如果類沒有構造方法呢?在這種情況下,一個缺省的構造方法(也叫"無參構造方法")由java編譯器自動生成。缺省構造方法只有在類沒有任何其它的構造方法時才產生。

更深入的明白這個,假設在文件A.java中有這樣的代碼:



public class A {

public static void main(String args[]) {

A aref = new A();

}

}



如果你想編譯然后列出A.class 中的字節碼,輸入下面的內容:



$ javac A.java

$ javap -c -classpath . A



輸出:



Compiled from A.java

public class A extends java.lang.Object {

public A();

public static void main(java.lang.String[]);

}



Method A()

 0 aload_0

 1 invokespecial #1 <Method java.lang.Object()>

 4 return



Method void main(java.lang.String[])

 0 new #2 <Class A>

 3 dup

 4 invokespecial #3 <Method A()>

 7 astore_1

 8 return



在main 中,注意對 A 的構造方法的調用(就是invokespecial 行),以及A的構造方法中產生的類似的對Object 構造方法的調用。

如果父類沒有缺省構造方法,你必須明確使用"super(args)"調用父類的某個構造方法,例如,下面是一個錯誤的用法:



class A {

A(int i) {}

}



class B extends A {}



在上面的情況下, A 沒有缺省的構造方法,但是B的構造方法必須調用A的某個構造方法。

讓我們來看看初始化的另一個例子:



class A {

A() {

System.out.println("A.A called");

}

A(int i) {

this();

System.out.println("A.A(int) called");

}

}



class B extends A {

int i = f();

int j;



{

j = 37;

System.out.println("initialization block executed");

}



B() {

this(10);

System.out.println("B.B() called");

}



B(int i) {

super(i);

System.out.println("B.B(int) called");

}



int f() {

System.out.println("B.f called");

return 47;

}

}



public class CtorDemo3 {

public static void main(String args[]) {

B bobj = new B();

}

}



程序的輸出是:



A.A called

A.A(int) called

B.f called

initialization block executed

B.B(int) called

B.B() called



這個例子明確使用super() 和 this() 調用。this()調用是調用同一個類中的另一個構造方法;這個方法被稱為“顯式構造方法調用”。當那樣的構造方法被調用,它將執行通常的super() 過程以及后續的操作。這意味著A.A 的方法體在A.A(int)之前執行,而這兩個都在B.B(int) 和B.B 前執行。

如果返回第一個例子,你就可以回答為什么打印的是2而不是1。B 沒有構造方法,因此生成一個缺省構造方法,然后它調用super(),然后調用A 產生的缺省構造方法。

然后A中的成員被初始化,成員a 被設置為方法f()的值,但是因為B 對象正被初始化,f() 返回值2。換句話說,調用的是B中的f()方法。

A產生的構造方法體被執行,然后B的成員被初始化,而b 被賦予值a,也就是2。最后,B的構造方法被執行。

最后一個例子說明了第一個例子的一個小小的變異版本:



class A {

int a = f();

int f() {

return 1;

}

}



class B extends A {

int b = 37;

int f() {

return b;

}

}



public class CtorDemo4 {

public static void main(String args[]) {

B bobj = new B();

System.out.println(bobj.a);

System.out.println(bobj.f());

}

}



程序的輸出是:



0

37



你可能會期望輸出的兩個值bobj.a 和bobj.f()是一樣的,但是正如你看到的他們不一樣。這是正確的,即使是在a是從B的f方法中初始化的并且打印的是a 和 B的 f 方法的值。

這兒的問題是當a通過對B的f方法調用而初始化,而該方法返回成員b的值,而該成員還沒有被初始化。因為這個,b的值就是剛開始的初始值0。

這些例子解釋了編程中重要的一點――在對象的構造階段調用可重載的方法是不明智的。



主站蜘蛛池模板: 热の综合热の国产热の潮小说 | 伊人网综合在线 | 午夜福利国产一级毛片 | 四虎精品成人免费视频 | 日本在线精品 | 亚洲第1页| 日本视频一区二区三区 | 三级大黄| 青娱乐精品视频在线观看 | 亚洲成av人片在线观看 | 人人公开免费超级碰碰碰视频 | 日本porno动漫 | 天天干天天操天天 | 亚洲精品123区 | 亚洲大片免费看 | 色综合久久一本首久久 | 天天拍天天色 | 永久免费精品影视网站 | 五月婷婷丁香在线 | 午夜久久久 | 日韩欧美图片 | 青青草国产97免久久费观看 | 亚洲国产一成人久久精品 | 天天操天天舔 | 一区二区视频网 | 欧洲真实呦女网站 | 亚洲国产精品久久久天堂麻豆 | 在线观看免费黄视频 | 日韩精品免费观看 | 日美一级毛片 | 午夜男人的天堂 | 天堂影视网 | 最新版天堂中文在线官网 | 欧美一级特黄刺激大片视频 | 在线视频久 | 一二三四视频日本高清 | 亚洲日本成人 | 日韩经典欧美一区二区三区 | 欧美中文字幕在线看 | 天天搞天天色 | 一二三四日本高清免费看 |