Summer_More_More_Tea
Summer_More_More_Tea

Reputation: 13356

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!

Upvotes: 4

Views: 380

Answers (1)

Neil Essy
Neil Essy

Reputation: 3607

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.

  1. Superclasses are fully initialized before subclasses.
  2. Otherwise, in declaration order.

Upvotes: 3

Related Questions