[英]Problem with entry set of java.util.Map
I'm having a strange problem with the following code works. 我遇到以下代码的奇怪问题。
Map<String, Object> map = new HashMap<String, Object>();
for(Entry<String, Object> entry : map.entrySet()) {
//
}
while the code below does not compile. 而下面的代码不编译。
Map map = new HashMap();
for(Entry entry : map.entrySet()) { // compile error here
//
}
Any clues? 有线索吗?
The entrySet
method signature is Set<Map.Entry<K, V>> entrySet()
so you can only refer to Map.Entry
if you've declared the generic types in the declaration like you did in the first example. entrySet
方法签名是Set<Map.Entry<K, V>> entrySet()
因此如果您在声明中声明了泛型类型,就像在第一个示例中所做的那样,您只能引用Map.Entry
。 In the second you're using raw types, so it's essentially Set<Object> entrySet()
and you'd need a cast for it to work, eg 在第二个你正在使用原始类型,所以它基本上是
Set<Object> entrySet()
,你需要一个强制转换才能工作,例如
final Map map = new HashMap();
for(final Entry entry : (Set<Entry>)map.entrySet()) {
//
}
Burt has the right reason and Henning expands on it in the comments. 伯特有正当的理由,亨宁在评论中对其进行了扩展。 When referencing a member of a raw type, generics don't come into play at all , even generics that don't rely on the type parameter .
当引用原始类型的成员,仿制药不来发挥作用的一切 , 甚至不依赖于类型参数的泛型 。
As an example, this should compile just fine... 作为一个例子,这应该编译得很好......
public class DataHolder<T> {
public List<T> ts;
public List<String> strings = new ArrayList<String>();
}
//...
DataHolder holder = new DataHolder();
holder.strings.add(Integer.valueOf(42));
...even though T
doesn't need to be mapped to a concrete type to know what the type of strings
should be. ...即使
T
不需要映射到具体类型来知道strings
的类型应该是什么。
This is true for generic member methods as well, which is what you are running into. 对于通用成员方法也是如此,这正是您遇到的问题。
entrySet
returns the raw type Set
, not Set<Entry>
, even though the type parameters would not need to be known to return a Set<Entry>
. entrySet
返回原始类型Set
,而不是Set<Entry>
,即使不需要返回Set<Entry>
也不需要知道类型参数。 The behaviour is documented in the Java Language Specification, section 4.8 : 该行为记录在Java语言规范的4.8节中 :
The type of a constructor (§8.8), instance method (§8.8, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the erasure of its type in the generic declaration corresponding to C. The type of a static member of a raw type C is the same as its type in the generic declaration corresponding to C.
未从其超类或超接口继承的原始类型C的构造函数(第8.8节), 实例方法 (第8.8节,第9.4节)或非静态字段(第8.3节)M的类型是其类型的擦除在对应于C的泛型声明中。原始类型C的静态成员的类型与对应于C的泛型声明中的类型相同。
It's a very "gotcha" rule. 这是一个非常“陷入困境”的规则。
Java Class Generics and Method Generics conflicts Java类泛型和方法泛型冲突
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.