我是新來的Java從Scala和Scala的對象初始化序列的固有層次混淆。 IIRC,在Java中,如果子類的一個對象被初始化,那麼它的基類的構造函數在它自己的構造函數的任何代碼之前被調用。在scala中,我得到完全不同的行爲。請看下面的例子:對象初始化序列在固有的層次結構中的斯卡拉
class Point(val x: Int, val y: Int){
val name = this.makeName;
def makeName: String = {
println("makeName at super.");
"[" + x + ", " + y + "]";
}
override def toString: String = name;
}
class ColorPoint(override val x: Int, override val y: Int, var color: String) extends Point(x, y) {
// key statement
println(name);
override def makeName: String = {
println("makeName at sub.");
super.makeName + ":" + myColor;
}
val myColor = color;
override def toString: String = name;
}
讓我們只考慮javap
傾倒的ColorPoint
構造函數的字節碼。如果代碼包括關鍵語句println(name);
的字節碼是
public ColorPoint(int, int, java.lang.String);
Code:
0: aload_0
1: aload_3
2: putfield #13; //Field color:Ljava/lang/String;
5: aload_0
6: iload_1
7: iload_2
8: invokespecial #18; //Method Point."<init>":(II)V
11: getstatic #24; //Field scala/Predef$.MODULE$:Lscala/Predef$;
14: aload_0
15: invokevirtual #28; //Method name:()Ljava/lang/String;
18: invokevirtual #32; //Method scala/Predef$.println:(Ljava/lang/Object;)V
21: aload_0
22: aload_3
23: putfield #34; //Field myColor:Ljava/lang/String;
26: return
我們可以看到現場myColor
是基類的初始化後invokespecial
初始化後,即。
如果我註釋掉聲明println(name);
的字節碼是:
public ColorPoint(int, int, java.lang.String);
Code:
0: aload_0
1: aload_3
2: putfield #13; //Field color:Ljava/lang/String;
5: aload_0
6: aload_3
7: putfield #15; //Field myColor:Ljava/lang/String;
10: aload_0
11: iload_1
12: iload_2
13: invokespecial #20; //Method Point."<init>":(II)V
16: return
我們看到,現場myColor
只是invokespecial
之前被初始化,即基地初始化之前。
那麼是什麼原因?任何文件/文章都指定了這種行爲?
順便說一句,我的scala版本是2.7.7final(OpenJDK Server VM,Java 1.6.0_20)。感謝和最好的問候!
在這樣一個過時的版本上運行的任何理由?你需要幫助遷移嗎? – soc
@soc已經升級了,謝謝。 –