If three public interfaces are defined as:
public interface One{}
public interface Two{}
public interface Three{}
And another class, Super, is defined as:
public class Super {
public static <E extends One & Two & Three> void hmm(E item) {}
}
Why does the following subclass of Super give a compile error?
public class Subber extends Super{
public static void hmm(One item) {}
}
I would expect the above method to simply hide the method from Super, but that does not seem to be the case.
The JLS (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.
where a subsignature is defined in 8.4.2 as:
Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.
The signature of a method m1 is a subsignature of the signature of a method m2 if either: m2 has the same signature as m1, or the signature of m1 is the same as the erasure (§4.6) of the signature of m2.
The erasure of a type variable is the erasure of its leftmost bound, as per JLS 4.6, so: As far as I understand, Subber's hmm method is the same as the erasure of Super's hmm method, and would therefore be a subsignature of Super's hmm, thus meaning it would hide Super's hmm. However, the error message I get (from eclipse), which doesn't seem to make sense given the above is: "The method hmm(One) of type Subber has the same erasure as hmm(E) of type Super but does not hide it." What am I missing?
Edit: The precise error message, where the main method simply contains Subber.hmm(null);
is:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Name clash: The method hmm(One) of type Subber has the same erasure as hmm(E) of type Super but does not hide it
at base/testpack4.Subber.hmm(Subber.java:4)
at base/testpack4.Main.main(Main.java:5)
Could someone explain why Subber's method does not compile, citing a credible source (preferably the JLS)?
„...Could someone explain why Subber's method does not compile...“
I implemented the code you listed; verbatim. And my Main.main(String[])
compiles fine with a call to Subber.hmm(null)
and Subber.hmm(One)
.
The only thing different I did was introduce a new Four
interface that meets the requirements of the type parameter section of <E extends One & Two & Three> void Super.hmm(E)
.
Then I passed an instance of Four
into Subber.hmm(One)
to confirm that Super.hmm(E)
wasn't being called; proving it is actually hidden.
„...citing a credible source (preferably the JLS)?...“
That implementation behaves exactly as the JLS spec that you cited describes.