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.
Yes, as mentioned we can call all the members of a class (methods, variables, and constructors) from instance methods or, constructors.
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.
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.
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With