[英]Java non-generic method hiding generic method with intersection types
If three public interfaces are defined as:如果三个公共接口定义为:
public interface One{}
public interface Two{}
public interface Three{}
And another class, Super, is defined as:而另一个class,Super,定义为:
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?为什么 Super 的以下子类会出现编译错误?
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.我希望上述方法可以简单地隐藏 Super 的方法,但似乎并非如此。
The JLS (8.4.8.2) says: JLS (8.4.8.2) 说:
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.
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 否则可以访问(第 6.6 节)以在 C 中进行编码。
where a subsignature is defined in 8.4.2 as:其中子签名在 8.4.2 中定义为:
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.
如果两个方法或构造函数 M 和 N 具有相同的名称、相同的类型参数(如果有)(第 8.4.4 节),并且在将 N 的形式参数类型调整为类型参数之后,则它们具有相同的签名的 M,形参类型相同。
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.
方法 m1 的签名是方法 m2 签名的子签名,如果: m2 与 m1 具有相同的签名,或者 m1 的签名与 m2 签名的擦除(第 4.6 节)相同。
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.根据 JLS 4.6,类型变量的擦除是其最左边界的擦除,所以:据我了解,Subber 的 hmm 方法与 Super 的 hmm 方法的擦除相同,因此将是 Super 的 hmm 的子签名,因此意味着它会隐藏 Super 的嗯。 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."
但是,我收到的错误消息(来自 eclipse),鉴于上述情况,这似乎没有意义:“Subber 类型的方法 hmm(One) 与 Super 类型的 hmm(E) 具有相同的擦除,但没有把它藏起来。” What am I missing?
我错过了什么?
Edit: The precise error message, where the main method simply contains Subber.hmm(null);
编辑:精确的错误消息,其中主要方法只包含
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)?有人可以引用可靠的来源(最好是 JLS)解释为什么 Subber 的方法无法编译吗?
„ ...Could someone explain why Subber's method does not compile... “
“ ……有人能解释一下为什么 Subber 的方法无法编译吗…… ”
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)
.我的
Main.main(String[])
通过调用Subber.hmm(null)
和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)
.我唯一不同的是引入了一个新的
Four
接口,它满足<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;然后我将
Four
的实例传递给Subber.hmm(One)
以确认Super.hmm(E)
没有被调用; proving it is actually hidden.证明它实际上是隐藏的。
„ ...citing a credible source (preferably the JLS)?... “
„ ...引用可靠来源(最好是 JLS)?... “
That implementation behaves exactly as the JLS spec that you cited describes.该实现的行为与您引用的 JLS 规范完全相同。
The type for E is still undefined, you can go and parameterize it via setting the E generic for the Super class and define it in the Subber class: E 的类型仍然未定义,您可以 go 并通过设置 Super class 的 E 泛型对其进行参数化,并在 Subber class 中定义它:
public class Super<E> {
public static <E extends One & Two & Three> void hmm(E item) {}
}
public class Subber extends Super<One> {
public static void hmm(One item) {}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.