Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Parasoft Jtest 2021.1

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, §8.4.8.2 "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 Hiding term is used in context of a class method (or field) that has the same signature as the corresponding class method (or field) in the superclass or superinterface.

The difference between these two is that the overridden method gets invoked from the subclass while the hidden method may get invoked from either the superclass or the subclass, depending on how it is invoked (name qualification).

Noncompliant Code Example

To differentiate between overriding and hiding, a common nomenclature is used. The method to be invoked is decided at either compile time (if the base method is static, as in this noncompliant code example) according to the type of the qualifier or at run time otherwise (for non-static methods). A qualifier is a part of the invocation expression before the dot (for example, the variables admin and user in this noncompliant code example).

This noncompliant example attempts to override a static method but fails to consider it as a hiding case. As a result the displayAccountStatus() method of the superclass is invoked on both the calls. Moreover, expressions that are normally used for dynamic dispatch while overriding have been used even though achieving this is impossible with static methods, causing it to print  Account details for admin despite being instructed to choose user rather than admin.

Code Block
bgColor#FFCCCC

class GrantAccess {
  public static void displayAccountStatus() {
    System.out.printprintln("Account details for admin: XX");
  }
}

class GrantUserAccess extends GrantAccess {
  public static void displayAccountStatus() {
    System.out.printprintln("Account details for user: XX");
  }
}

public class StatMethod {
  public static void choose(String username) {
    GrantAccess admin = new GrantAccess();
    GrantAccess user = new GrantUserAccess();
    if (username.equals("admin")) {
      admin.displayAccountStatus();
    } else {
      user.displayAccountStatus();
    }
  }

  public static void main(String[] args) {
    choose("user");	
  }
}

Compliant Solution

This compliant solution correctly classifies this case as hiding and uses absolute, fully qualified class names GrantAccess and GrantUserAccess to clearly state the intent. Refrain from qualifying a static method invocation with an expression meant for dynamic dispatchIn 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.

Code Block
bgColor#ccccff

class GrantAccess {
  public static void displayAccountStatus() {
    System.out.print("Account details for admin: XX");
  }
}

class GrantUserAccess extends GrantAccess {
  @Override
  public static void displayAccountStatus() {
    System.out.print("Account details for user: XX");
  }
}

public class StatMethod {
  public static void choose(String username) {
    GrantAccess admin = new GrantAccess();
    GrantAccess user = new GrantUserAccess();

    if (username.equals("admin")) {
      GrantAccessadmin.displayAccountStatus();
    } else {
      GrantUserAccessuser.displayAccountStatus();
    }
  }
  
  public static void main(String[] args) {
    choose("user");	
  }
}

Wiki Markup
Note that "In a subclass, you can overload the methods inherited from the superclass. Such overloaded methods neither hide nor override the superclass methods—they are new methods, unique to the subclass." \[[Tutorials 2008|AA. Java References#Tutorials 08]\].

Wiki Markup
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 2005|AA. Java References#JLS 05]\]. Consequently, there may be no _hiding_ when the methods have different return types or {{throws}} clauses.

...

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 throws clauses.

Exceptions

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:

Code Block
bgColor#ccccff
  public static void choose(String username) {
    if (username.equals("admin")) {
      GrantAccess.displayAccountStatus();
    } else {
      GrantUserAccess.displayAccountStatus();
    }
  }

Risk Assessment

Confusing overriding and hiding can produce unexpected results.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MET11

MET07-J

low

Low

unlikely

Unlikely

medium

Medium

P2

L3

Automated Detection

TODO

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

Wiki Markup
\[[Tutorials 2008|AA. Java References#Tutorials 08]\] [Overriding and Hiding Methods|http://java.sun.com/docs/books/tutorial/java/IandI/override.html]
\[[Bloch 2005|AA. Java References#Bloch 05]\] Puzzle 48: All I Get Is Static
\[[JLS 2005|AA. Java References#JLS 05]\] 8.4.6.3 Requirements in Overriding and Hiding

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.

ToolVersionCheckerDescription
Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.MET07.AHSMDo not hide inherited "static" member methods

Bibliography


...

Image Added Image Added Image AddedMET10-J. For methods that return an array or collection prefer returning an empty array or collection over a null value      16. Methods (MET)      MET12-J. Follow the general contract while overriding the equals method