-
Bug
-
Resolution: Fixed
-
P4
-
12, 13, 14, 15
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.
"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.