Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8231970

8.4.8.2: Static methods of classes shouldn't hide static methods of interfaces

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 15
    • 12, 13, 14, 15
    • specification

      JLS14 8.4.8.2 says:

      "If a class C declares or inherits a static method m, then m is said to _hide_ any method m',
        where the signature of m is a subsignature (§8.4.2) of the signature of m',
        in the superclasses and superinterfaces of C that would otherwise be accessible (§6.6) to code in C."

      Hiding is observable because of the restrictions in 8.4.8.3. For example, it is a compile-time error if a (static) method returning String hides a (static) method returning int. However, javac has a more sophisticated definition of hiding than the quoted definition above, resulting in fewer actual compile-time errors than the quote would suggest. In particular, javac considers that a static method in a class hides static methods in superclasses but not in superinterfaces. In the code below, javac considers C::m to hide A::m (causing a compile-time error, as the inconsistent return types are material) but does not consider that C::n hides B::n (hence no error for C::n, as the inconsistent return types are immaterial).

      public class Hiding {
          static class A { static int m() { return 99; } }
          interface B { static int n() { return 99; } }

          static class C extends A implements B {
              static String m() { return "100"; } // error from javac
              static String n() { return "100"; } // no error from javac
          }
      }

      javac's behavior in this case parallels the specified treatment of overriding: an instance method declared in a class with an appropriate signature overrides a static method declared in a superclass (triggering an error), but never overrides a static method declared in a superinterface (see 8.4.8.1). An instance method declared in an interface never overrides a static method declared in a superinterface (see 9.4.1.1).

      javac's behavior also parallels the specified treatment of "hiding" in interfaces: a static method declared in an interface with an appropriate signature "in essence" hides an instance method declared in a superinterface, subjecting the static method to additional constraints (formally, this is not defined as "hiding", but the behavior is consistent with constraints on hiding for static methods declared in classes); however, a static method declared in an interface is subject to no such constraints with respect to static methods declared in superinterfaces (see 9.4.1).

      These behaviors are appropriate: because static interface methods are not inherited, there is no reason to place any restrictions on the return type, etc., of a method that shares a name with a static superinterface method.

            abuckley Alex Buckley
            dlsmith Dan Smith
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: