1
class Alpha
{
       String name = "Alpha";
       Alpha()
       {
           print();
       }
       void print()
       {
           System.out.println("Alpha Constructor");
       }
}
class Beta extends Alpha
{
       int i =   5;
       String name = "Beta";
       public static void main(String[] args)
       {
          Alpha a = new Beta();
          a.print();//Line1 executes Beta constructor
          System.out.println(a.name);//Line 2 displays Alpha instance variable
       }
       void print()
       {
           System.out.println(i);
       }
}

This program compiles successfully and displays the following output.

0
5
Alpha

Questions

a) I dont understand why Alpha's constructor did not get executed first.

I believe "super()" will be called implicitly by every child constructor first ...right ?.

b) If Beta's constructor is already executed then why "5" is printed ? (Second Line in Output)

The third line I kinda understand (i.e Alpha's own variable will be displayed because casting is not yet done on "a" instance variable)

Andy G
  • 19,232
  • 5
  • 47
  • 69
UnderDog
  • 3,173
  • 10
  • 32
  • 49
  • 1
    Where did that `0` come from? – Jeroen Vannevel Aug 25 '13 at 10:56
  • `0` is the output of the first run of `print` where `i` is not yet overridden. Both constructors call `print`, but at the time the `Alpha`constructor calls `print``i` is not yet initialized by the instance initializer. – Sebastian Aug 25 '13 at 11:02

4 Answers4

5

You are committing two "felonies" here:

  1. calling an overridable method from the constructor;
  2. declaring an instance variable in the subclass with the same name as the one in the superclass.

Both idioms result in surprising behavior. Specifically, 1. results in Beta#print being called from the Alpha's constructor, which results in printing 0 because you are invoking print on an unititialized instance of Beta. And this happens precisely because the superconstructor runs before the subclass constructor.

In summary, calling an overridden method from the constructor results in an unwanted reversal of the order of execution: control is transferred from the superclass constructor into the subclass method.

As for your question about why 5 is printed: a.print(), unlike a.name, is a method invocation subject to dynamic dispatch. So regardless of a's declared type (which is Alpha), the Beta#print method is invoked (the same happens in Alpha's constructor, but before the i variable is initialized).

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
4
class Alpha
{
       String name = "Alpha";
       Alpha()
       {
           print();

This one here actually invokes Beta.print(), because it @Overrides Alpha.print(). Since base class constructors are called first, the Beta part has not yet been initialized here, thus it prints 0 since...

       }
       void print()
       {
           System.out.println("Alpha Constructor");
       }
}
class Beta extends Alpha
{
       int i =   5;

this line of code has not yet been executed. Initialization within the class body is executed after the super class constructor (super()) but before the constructor body of the same class.

       String name = "Beta";
       public static void main(String[] args)
       {
          Alpha a = new Beta();
          a.print();//Line1 executes Beta constructor

Here, it will print 5, as initialization of Beta (a) is finished.

          System.out.println(a.name);//Line 2 displays Alpha instance variable
       }

And this is said method actually beeing called:

       void print()
       {
           System.out.println(i);
       }
}

Init/Invocation order:

  • Object.Object()
  • Alpha.<instance vars>
  • Alpha.<constructor body>
    • Beta.print() which overrides Alpha.print() (prints Beta.i, which is still 0 (default) )
  • Beta.<instance vars> (Here Beta.i will be initialized to 5)
  • Beta.<constructor body>
  • Beta.print() which overrides Alpha.print() (prints Beta.i, which finally is 5, since initialization is finished)
Sam
  • 7,778
  • 1
  • 23
  • 49
1

I dont understand why Alpha's constructor did not get executed first.

It did execute first. I don't know what made you think it didn't. Perhaps the output 0. That is because you invoked the overridden method in constructor, which will call the method print() in Beta class. Now, since at that point of time, the variable i hasn't been initialized yet, it will print 0. See this answer for more details. I've also written a blog post on this topic.

I believe "super()" will be called implicitly by every child constructor first ...right ?

Not always. When you chain the constructor of the same class using this(), super() won't be added. Else super class constructor will be chained.

If Beta's constructor is already executed then why "5" is printed ?

Why wouldn't it? Beta constructor will initialize i with 5. The initialization which you do at the point of declaration is moved to every constructor of your class by the compiler, after the super() or this() statement, whatever is there.

Community
  • 1
  • 1
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • Good to see your blog for the first time....You should write about regex stuffs in your blog.... – Akash KC Aug 25 '13 at 11:54
  • 1
    @LolCoder. Sure. As time permits, and more importantly, when I think I've something interesting to write on, will post it for sure. Thanks :) – Rohit Jain Aug 25 '13 at 11:58
0
  • Alpha's constructor does get executed first. If you put System.out.println("Alpha Ctr"); in Alpha() method you will notice Alpha Ctr getting printed.
  • The fact is that you've overridden print() method in child class Beta. Therefore Beta#print() gets executed instead of Alpha#print().

If you change Beta#print() little bit this behavior will be more clear:

void print() {
    System.out.println(name + ": " + i);
}

This will now print:

null: 0
Beta: 5
Alpha

Here it is prints null: 0 because variable name & i are uninitialized at the time of construction of parent class Alpha.

anubhava
  • 761,203
  • 64
  • 569
  • 643