我注意到“泛型行为”中HashMap
和EnumMap
之间存在惊讶(对我而言)。
这是什么意思?
请考虑以下两个代码段:
enum Types { A, B, C }
enum Wrong { A }
public class Test {
public static void main(String... args) {
EnumMap<Types, Integer> m = new EnumMap<Types, Integer>(Types.class);
EnumMap m1 = m;
m1.put(Wrong.A, 1);
}
}
出:
线程“main”中的异常java.lang.ClassCastException:class Wrong !=类类型
enum Types { A, B, C }
enum Wrong { A }
public class Test {
public static void main(String... args) {
HashMap<Types, Integer> m = new HashMap<Types, Integer>();
HashMap m1 = m;
m1.put(Wrong.A, 1);
}
}
出:
成功编译!
因此,HashMap
擦除fullfils但使用EnumMap
的相同代码 - 不是。为什么呢?
答案 0 :(得分:0)
您的第一个示例提供了一个例外,因为它期待类Types.class
的实例,但您添加了一个Wrong.A
的实例,它是一个不同的类。在第一个示例中,您执行删除了泛型,但它仅接受Types.class
实例的事实是此EnumMap
实例的属性 1}}因此没有泛型约束。
在第二个例子中没有这样的约束。没有这样的约束,因为您删除了泛型定义的约束,因此您可以放置Object
类型的所有内容。
答案 1 :(得分:0)
您的结论不正确:两种情况都会以同样的方式发生擦除。区别在于EnumMap对象在字段中为其键类型保留类对象的引用,并使用该类对象执行反射转换。这就是引起异常的原因,你可以从堆栈跟踪中看出来。
相反,普通地图使用未经检查的强制转换,即使对象的类型不正确(导致堆污染)也会成功。