Question

Je suis nouveau à rampe de Java et confus par la séquence d'initialisation d'objet de rampe dans une hiérarchie inhérente. IIRC, en Java, si un objet de sous-classe est initialisé, constructeur de sa classe de base est appelée avant tout code de son propre constructeur. Alors que dans scala, je reçois un comportement totalement différent. Prenons l'exemple suivant:

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;
}

Soit le code de considérer seulement l'octet du constructeur de ColorPoint jeté avec javap. Si le code inclut la déclaration clé println(name); le code octet est

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

Nous pouvons voir myColor de champ est initialisé après invokespecial, à savoir après l'initialisation de la classe de base.

Si je commente la déclaration println(name); le code octet est:

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

Nous voyons que myColor de champ est initialisé juste avant invokespecial, à savoir avant de base est initialisé.

Alors quelle est la raison? Tout document / article précise ce genre de comportement?

BTW, la version de mon scala est 2.7.7final (OpenJDK serveur VM Java 1.6.0_20). Merci et meilleures salutations!

Était-ce utile?

La solution

Le compilateur exécute simplement les choses dans l'ordre. Il y a une documentation ici.

https://github.com/paulp/scala-faq/wiki/ initialisation-ordre

La partie principale de c'est le suivant.

  1. Superclasses sont complètement initialisé avant les sous-classes.
  2. Dans le cas contraire, dans l'ordre de déclaration.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top