【发布时间】:2015-06-20 09:44:12
【问题描述】:
我发现 Maps、rawtypes 和泛型会发生一些有趣的事情。以下代码:
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
}
我收到关于类型不兼容的编译错误,即:“无法将对象强制转换为条目”。
如果没有变量再次存储,为什么entrySet() 上的迭代器会丢失类型信息?
rawtypes 不应该影响类型,所以Map.Entry 突然变成了一个对象。还是我弄错了?
【问题讨论】:
-
Set <Map.Entry> set = map.entrySet ();是允许的“未经检查的分配”。这就是允许第一个迭代器工作的原因。您可以通过在第二种情况下明确强制转换来获得相同的结果:for(Map.Entry entry : (Set<Map.Entry>)map.entrySet()) { } -
要遵循的最基本规则是:永远不要使用原始类型。它们很容易避免(通常用通配符参数替换,即
Set变成Set<?>),它们存在的唯一原因是向后兼容预泛型代码。 -
@JoachimSauer,同意,但我认为这主要是一个学术问题。编辑:好的,所以它不是学术的,但无论如何这是一个有趣的问题。
-
@Joachim 对。这在维护前泛型时代的遗留代码时无济于事,而且无论如何对这个问题都没有真正的建设性......
标签: java iterator type-erasure generics