When a class declares a static method m, the declaration of m hides any method m', where the signature of m is a subsignature of the signature of m' and the declaration of m' is both in the superclasses and superinterfaces of the declaring class and also would otherwise be accessible to code in the declaring class (The Java Language Specification, §126.96.36.199 "Hiding (by Class Methods)" [JLS 2015]).
An instance method defined in a subclass overrides another instance method in the superclass when both have the same name, number and type of parameters, and return type.
Hiding and overriding differ in the determination of which method is invoked from a call site. For overriding, the method invoked is determined at runtime on the basis of the specific object instance in hand. For hiding, the method invoked is determined at compile time on the basis of the specific qualified name or method invocation expression used at the call site. Although the Java language provides unambiguous rules for determining which method is invoked, the results of these rules are often unexpected. Additionally, programmers sometimes expect method overriding in cases where the language provides method hiding. Consequently, programs must never declare a class method that hides a method declared in a superclass or superinterface.
Noncompliant Code Example
In this noncompliant code example, the programmer hides the static method rather than overriding it. Consequently, the code invokes the
displayAccountStatus() method of the superclass, causing it to print
Account details for admin despite being instructed to choose
user rather than
In this compliant solution, the programmer declares the
displayAccountStatus() methods as instance methods by removing the
static keyword. Consequently, the dynamic dispatch at the call sites produces the expected result. The
@Override annotation indicates intentional overriding of the parent method.
The methods inherited from the superclass can also be overloaded in a subclass. Overloaded methods are new methods unique to the subclass and neither hide nor override the superclass method [Java Tutorials].
Technically, a private method cannot be hidden or overridden. There is no requirement that private methods with the same signature in the subclass and the superclass bear any relationship in terms of having the same return type or
throws clause, the necessary conditions for hiding [JLS 2015]. Consequently, hiding cannot occur when private methods have different return types or
MET07-J-EX0: Occasionally, an API provides hidden methods. Invoking those methods is not a violation of this rule provided that all invocations of hidden methods use qualified names or method invocation expressions that explicitly indicate which specific method is invoked. If the
displayAccountStatus() were a hidden method, for example, the following implementation of the
choose() method would be an acceptable alternative:
Confusing overriding and hiding can produce unexpected results.
Automated detection of violations of this rule is straightforward. Automated determination of cases in which method hiding is unavoidable is infeasible. However, determining whether all invocations of hiding or hidden methods explicitly indicate which specific method is invoked is straightforward.
|Do not hide inherited "static" member methods
Puzzle 48, "All I Get Is Static"