Subtle call to inherited method¶
ID: java/subtle-inherited-callKind: problemSecurity severity: Severity: warningPrecision: very-highTags: - quality - maintainability - readabilityQuery suites: - java-security-and-quality.qls
Click to see the query in the CodeQL repository
If a call is made to a method from an inner class A, and a method of that name is defined in both a superclass of A and an outer class of A, it is not clear to a programmer which method is intended to be called.
Example¶
In the following example, it is not clear whether the call toprintMessage calls the method that is defined inOuter orSuper.
publicclassOuter{voidprintMessage(){System.out.println("Outer");}classInnerextendsSuper{voidambiguous(){printMessage();// Ambiguous call}}publicstaticvoidmain(String[]args){newOuter().newInner().ambiguous();}}classSuper{voidprintMessage(){System.out.println("Super");}}
Inherited methods take precedence over methods in outer classes, so the method in the superclass is called. However, such situations are a potential cause of confusion and defects.
Recommendation¶
Resolve the ambiguity by explicitly qualifying the method call:
To specify the outer class, prefix the method with
Outer.this..To specify the superclass, prefix the method with
super..In the above example, the call toprintMessagecould be replaced by eitherOuter.this.printMessageorsuper.printMessage, depending on which method you intend to call. To preserve the behavior in the example, usesuper.printMessage.
References¶
Inner Classes Specification:What are top-level classes and inner classes?.