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. 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, e.g.
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.
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>
. The behaviour is documented in the Java Language Specification, section 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.
It's a very "gotcha" rule.
See also
Java Class Generics and Method Generics conflicts
精彩评论