根据Java关于类型擦除和有界类型参数的文档,我理解在下面的代码示例中,两个版本doStuff()
将具有相同的擦除,因此不会编译.我的目标是超载doStuff()
以接收ClassOne
和收集ClassTwo
.
import java.util.List;
class Example {
class ClassOne {
}
class ClassTwo {
}
public void doStuff(List<ClassOne> collection) {
}
public void doStuff(List<ClassTwo> collection) {
}
}
Run Code Online (Sandbox Code Playgroud)
类型擦除的机制包括以下步骤:
· 如果类型参数是无界的,则用泛型或对象替换泛型类型中的所有类型参数.因此,生成的字节码仅包含普通的类,接口和方法.
因此,我应该能够应用一个绑定,然后它将编译,因为现在类型擦除版本的doStuff重载了两个不同的签名(声明的上限).例:
class Example {
class ClassOne {
}
class ClassTwo {
}
public <U extends ClassOne> void doStuff(List<U> collection) {
}
public <U extends ClassTwo> void doStuff(List<U> collection) {
}
}
Run Code Online (Sandbox Code Playgroud)
第二个例子实际上没有编译并给出以下错误:
错误:(15,36)java:name clash:doStuff(java.util.List)和doStuff(java.util.List)具有相同的擦除
任何人都可以向我解释这个吗?
问题是,这List<U>
将减少到List
你的两种方法.(擦除后你不能拥有List<ClassOne>
或List<Object>
离开.)
您引用的段落意味着可以拥有以下声明:
class Example {
class ClassOne {
}
class ClassTwo {
}
public <U extends ClassOne> void doStuff(U foo) {
}
public <U extends ClassTwo> void doStuff(U foo) {
}
}
Run Code Online (Sandbox Code Playgroud)
这里泛型参数将分别替换为ClassOne
和ClassTwo
,它们可以正常工作.