Non-final method invocation in constructor¶
ID: java/non-final-call-in-constructor
Kind: problem
Severity: error
Precision: very-high
Tags:
- reliability
- correctness
- logic
Query suites:
- java-security-and-quality.qls
Click to see the query in the CodeQL repository
If a constructor calls a method that is overridden in a subclass, it can cause the overriding method in the subclass to be called before the subclass has been initialized. This can lead to unexpected results.
Recommendation¶
Do not call a non-final method from within a constructor if that method could be overridden in a subclass.
Example¶
In the following example, executing new Sub("test") results in a NullPointerException. This is because the subclass constructor implicitly calls the superclass constructor, which in turn calls the overridden init method before the field s is initialized in the subclass constructor.
public class Super {
public Super() {
init();
}
public void init() {
}
}
public class Sub extends Super {
String s;
int length;
public Sub(String s) {
this.s = s==null ? "" : s;
}
@Override
public void init() {
length = s.length();
}
}
To avoid this problem:
- The
initmethod in the super constructor should be madefinalorprivate. - The initialization that is performed in the overridden
initmethod in the subclass can be moved to the subclass constructor itself, or delegated to a separate final or private method that is called from within the subclass constructor.
References¶
- J. Bloch, Effective Java (second edition), pp. 89–90. Addison-Wesley, 2008.
- The Java Tutorials: Writing Final Classes and Methods.

