I have found something interesting to happen with Maps, rawtypes and generics. Following code:
static {
Map map = new HashMap ();
Set &l
Your example makes it look like you have type information that you never had. You have written:
Map map = new HashMap ();
Set set = map.entrySet();
for (Map.Entry entry : set) {} // fine
for (Map.Entry entry : map.entrySet()) {} // compilation error
But map.entrySet()
is returning Set
, not Set
. You've performed an unchecked assignment which "adds" type information.
In the second for loop, we don't know what's inside the Set
, so we can't iterate over Set
without an explicit cast.
For example, compare the original example to this one where we don't "add" type information with the unchecked assignment.
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
In this case, both for loops produce a compilation error.
This 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.