Secuencia de inicialización de objetos en scala en una jerarquía inherente
Pregunta
Soy nuevo en scala de java y estoy confundido por la secuencia de inicialización de objetos de scala en una jerarquía inherente. IIRC, en Java, si se inicializa un objeto de subclase, se invoca el constructor de su clase base antes que cualquier código de su propio constructor. Mientras estoy en Scala, obtengo un comportamiento totalmente diferente. Considere el siguiente ejemplo:
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;
}
Consideremos el código de bytes del constructor de ColorPoint
volcado con javap
. Si el código incluye la declaración clave println(name);
, el código de bytes es
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
Podemos ver que el campo myColor
se inicializa después de invokespecial
, es decir, después de la inicialización de la clase base.
Si comento la declaración println(name);
, el código de bytes es:
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
Vemos que el campo myColor
se inicializa justo antes de invokespecial
, es decir, antes de que se inicialice la base.
Entonces, ¿cuál es el motivo? ¿Algún documento / artículo especifica este tipo de comportamiento?
Por cierto, la versión de mi scala es 2.7.7final (OpenJDK Server VM, Java 1.6.0_20). ¡Gracias y saludos cordiales!
Solución
El compilador simplemente está ejecutando las cosas en orden.Hay algo de documentación aquí.
https://github.com/paulp/scala-faq/wiki/Orden de inicialización
La parte principal es la siguiente.
- Las superclases se inicializan completamente antes que las subclases.
- De lo contrario, en orden de declaración.