Vog*_*612 6 java generics type-erasure
我有一个相当中心的类负责一些Utility方法.我想为声明如下的方法提供额外的重载:
public static void removeDuplicated(Collection fullList, Collection itemsToRemove) {
//implementation stripped for brevity
}
Run Code Online (Sandbox Code Playgroud)
既然我不喜欢Rawtypes,我将这些集合指定为我可以预期的最小公分母:
public static void removeDuplicated(Collection<Map<?,?>> fullList,
Collection<Map<?,?>> itemsToRemove) {}
Run Code Online (Sandbox Code Playgroud)
到目前为止这么好,这摆脱了rawtypes警告和everthing的罚款到现在为止.
我继续为我的重载编写方法标题:
public static <T extends TeObjectWrapper> void removeDuplicated(
Collection<T> fullList, Collection<Map<?,?>> itemsToRemove) {}
Run Code Online (Sandbox Code Playgroud)
这是eclipse(随后通过ant使用javac6进行编译)给出了以下错误消息:
方法的擦除与
removeDuplicated(Collection<T>, Collection<? extends Map<?,?>>)类型[Utilites-Class]中的另一种方法相同
现在,由于我已经遇到了通配符泛型及其删除问题,我尝试通过替换未绑定的通配符来完全指定内容Object.错误消息仍然存在.
根据我的理解,第一个现有的重载应该擦除,Collection<Map<Object, Object>>第二个应该擦除Collection<TeObjectWrapper>.
如果TeObjectWrapper实现了Map(或扩展的Map的实现类之一),那么这些可能是相同擦除的唯一方法是,但事实并非如此.这可以在TeObjectWrapper的超类型层次结构中看到:

为什么编译器认为擦除相同,我怎么能让他不这么认为呢?
它们都擦除了public static void removeDuplicated(Collection, Collection).整个参数化被删除.你需要给他们不同的名字.
从4.6.类型擦除:
类型擦除是类型的映射(从不参数化类型或类型变量).
类型擦除还将构造函数或方法的签名映射到没有参数化类型或类型变量的签名.
擦除意味着:通用的一切都消失了.
(但是,作为一个有趣的边注,一般的信息是 存在于类文件.超载规则是由于Java的规范给定,不一定是因为它不是技术上是可行的方式.它更多的向后兼容的事情,允许遗留的非泛型类覆盖泛型方法.如果在该语言的未来版本中删除了原始类型,则可以允许这样的重载.)