Non-final method invocation in constructor¶
ID: java/non-final-call-in-constructor
Kind: problem
Security severity: 
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 made- finalor- private.
- 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. 



