Search code examples
javafinal

Why should methods called from a class constructor be final?


I'm a Java novice and I was trying to make sense of the following line from the tutorial at the Oracle website: https://docs.oracle.com/javase/tutorial/java/IandI/final.html

Methods called from constructors should generally be declared final. If a constructor calls a non-final method, a subclass may redefine that method with surprising or undesirable results.

I tried reading it multiple times trying to make sense of how a method called from a constructor can be redefined by a subclass. Should I assume the method being called by the constructor is one declared within the class of the constructor? And why should a method be declared final if it's called from within a constructor? (As opposed to from within a nested class or within another method?) I wasn't able to wrap my head around that statement. An example would be great.


Solution

  • This is valid code (compiles):

    class Person {
        Person() {
            init();
        }
    
        void init() {
            // do stuff
        }
    }
    
    class Employee extends Person {
        Employee() {
            super();
        }
    
        void init() {
            // do something else
        }
    }
    

    And it's highly suspicious. Because Person.init might do something critical for the integrity of the class, and there's no guarantees that Employee.init will do it too.

    Restricting Person.init to private is not good enough. Employee.init remains valid, but it will shadow Person.init, which will be simply very misleading. It's best to make Person.init final, which make prohibit creating Employee.init.