以下代码无法编译,这让我感到惊讶。任何人都可以解释原因吗?
Params.java:
public interface Params {
<E> E test(Class<E> cls);
interface MoreParams extends Params {
@Override
<E, F> E test(Class<E> cls);
}
}
编译:
Params.java:6: error: name clash: <E#1,F>test(Class<E#1>) in
MoreParams and <E#2>test(Class<E#2>) in Params have the same
erasure, yet neither overrides the other
<E, F> E test(Class<E> cls);
^
where E#1,F,E#2 are type-variables:
E#1 extends Object declared in method <E#1,F>test(Class<E#1>)
F extends Object declared in method <E#1,F>test(Class<E#1>)
E#2 extends Object declared in method <E#2>test(Class<E#2>)
Params.java:5: error: method does not override or implement a
method from a supertype
@Override
^
2 errors
如果相关,我使用java-8-oracle
,javac
版本1.8.0_25
。
似乎额外的泛型类型参数对类型签名没有实际影响,那为什么它会打破覆盖?
答案 0 :(得分:1)
我认为这可能与二进制兼容性有关,尽管您获得的确切错误消息可能会令人困惑。
考虑在添加MoreParams
接口之前编写的代码:
Params params = new ParamsSubClass();
String str1 = params.test(String.class);
String str2 = params.<>test(String.class);
String str3 = params.<String>test(String.class);
如果您使用类似ParamsSubClass
之类的人而不是人工MoreParamsSubClass
,那么涉及str1
和str2
的行仍将有效,然而涉及str3
的行将不再起作用,因为需要两个类型参数,因此代码不是二进制兼容的。
因此,当您更改类型参数时,您似乎无法覆盖方法,因为这会破坏二进制兼容性。