Object initialization sequence in scala in an inherent hierarchy
문제
I'm new to scala from java and confused by sequence of object initialization of scala in an inherent hierarchy. IIRC, in Java, if an object of sub-class is initialized, constructor of its base class is invoked before any code of its own constructor. While in scala, I get totally different behavior. Consider the following example:
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;
}
Let's just consider byte code of constructor of ColorPoint
dumped with javap
. If the code include the key statement println(name);
the byte code is
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
We can see field myColor
is initialized after invokespecial
, i.e. after initialization of the base class.
If I comment out the statement println(name);
the byte code is:
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
We see that field myColor
is initialized just before invokespecial
, i.e. before base is initialized.
Then what's the reason? Any document/article specifies this kind of behavior?
BTW, version of my scala is 2.7.7final (OpenJDK Server VM, Java 1.6.0_20). Thanks and Best Regards!
해결책
The compiler is simply executing things in order. There is some documentation here.
https://github.com/paulp/scala-faq/wiki/Initialization-Order
The main part from it is the following.
- Superclasses are fully initialized before subclasses.
- Otherwise, in declaration order.