Vog*_*612 5 java generics iterator type-erasure
我发现了地图,原型和泛型有趣的事情.以下代码:
static {
Map map = new HashMap ();
Set <Map.Entry> set = map.entrySet ();
for (Map.Entry entry : set) {} // fine
for (Map.Entry entry : map.entrySet()) {} // compilation error
}
Run Code Online (Sandbox Code Playgroud)
我收到关于类型不兼容的编译错误,即:"对象无法转换为条目".
entrySet()如果没有变量再次存储它,为什么迭代器会丢失类型信息?
rawtypes不应该影响类型,因此Map.Entry突然是一个对象.还是我弄错了?
您的示例使您看起来拥有您从未拥有的类型信息.你写:
Map map = new HashMap ();
Set <Map.Entry> set = map.entrySet();
for (Map.Entry entry : set) {} // fine
for (Map.Entry entry : map.entrySet()) {} // compilation error
Run Code Online (Sandbox Code Playgroud)
但是map.entrySet()回来了Set,不是Set <Map.Entry>.您已执行未选中的作业,该作业会"添加"类型信息.
在第二个for循环中,我们不知道里面是什么Set,所以我们不能在Set <Map.Entry>没有显式强制转换的情况下迭代.
例如,将原始示例与我们不使用未选中的分配"添加"类型信息的示例进行比较.
Map map = new HashMap();
Set set = map.entrySet();
for (Map.Entry entry : set) {
} // Object cannot be cast to Entry
for (Map.Entry entry : map.entrySet()) {
} // Object cannot be cast to Entry
Run Code Online (Sandbox Code Playgroud)
在这种情况下,两个for循环都会产生编译错误.
Java语言规范第4.8节中介绍了此行为:
未从其超类或超接口继承的原始类型C 的构造函数(第8.8节),实例方法(第8.8节,第9.4节)或非静态字段(第8.3节)M的类型是其类型的擦除在对应于C的泛型声明中.原始类型C的静态成员的类型与对应于C的泛型声明中的类型相同.