根据Java关于Type Erasure和Bounded Type Parameters的文档,我理解在下面的代码示例中,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) {
}
}
类型擦除的机制包括以下步骤:
·如果类型参数是无界的,则替换泛型类型中的所有类型参数及其边界或Object。因此,生成的字节码只包含普通的类,接口和方法。
因此,我应该能够应用一个绑定然后它会编译,因为现在类型擦除版本的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) {
}
}
第二个例子实际上没有编译并给出以下错误:
错误:(15,36)java:name clash:doStuff(java.util.List)和doStuff(java.util.List)具有相同的擦除
任何人都可以向我解释这个吗?
答案 0 :(得分:8)
问题是,在您的两种方法中,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) {
}
}
这里的通用参数将分别由ClassOne
和ClassTwo
替换,效果很好。