1

I have a confusion about this problem in the process of reading Effective Java about the principle of 'Constructors must not invoke overridable methods, directly or indirectly', that can be explained by below code snippet.

 public class Hello {
     public static void main(String[] args) {
    new Sub();
    }
 }

class Super {
   Super() {
    foo();
}

   void foo() {
    System.out.println("Super");
   }
 }

class Sub extends Super {
    Sub() {
      foo();
    }

   @Override
   void foo() {
    System.out.println("Sub");
   }
 }

The result is

Sub
Sub

It seems that in the process of initialization, both Super and Sub all invoke Sub's foo() method, the confusion is that for Super, why does it invoke its child's foo() method instead of itself?

Sunny
  • 181
  • 1
  • 7
  • 3
    because you create a `Sub` and `Sub` did override `Super#foo`. So at runtime it executes `Sub#foo`. If you would like to know why, that´s the prinicple of [Polymorphism](https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html) – SomeJavaGuy Aug 16 '16 at 07:44
  • Constructor doesn't create object, `new` keyword does. Code in constructor only initialize object returned by `new` to proper state but object is still the same in both constructors code and in your case its class is `Sub` not `Super` which is why thanks to dynamic-binding (mechanism of polymorphism) code of `Sub#foo` was invoked. Now where is that duplicate... – Pshemo Aug 16 '16 at 07:50
  • As a side note, the reason for this principle is that if you'd call overridable methods in constructor those methods might try to access not-yet initialized data (since the constructors are executed top-down). – Thomas Aug 16 '16 at 08:47

0 Answers0