Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should methods called from a class constructor be final? [duplicate]

Tags:

java

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.

like image 429
Parapan Avatar asked Dec 26 '14 21:12

Parapan


People also ask

Can you call methods from a constructor?

Yes, as mentioned we can call all the members of a class (methods, variables, and constructors) from instance methods or, constructors.

Why should you avoid calling abstract methods inside its constructor?

If run() depends on any state in Derivative, it can fail. Show activity on this post. It's a very bad practice to call an abstract method from a constructor. Methods called from constructors should always be private or final, to prevent overriding.

Is it bad practice to call methods in constructor?

Calling instance method in constructor is dangerous as the object is not yet fully initialized (this applies mainly to methods than can be overridden). Also complex processing in constructor is known to have a negative impact on test-ability.

Why can't a constructor be final?

The child class inherits all the members of the superclass except the constructors. In other words, constructors cannot be inherited in Java therefore you cannot override constructors. So, writing final before constructors makes no sense. Therefore, java does not allow final keyword before a constructor.


1 Answers

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.

like image 86
janos Avatar answered Oct 03 '22 00:10

janos