I do not understand why I get a warning (unchecked cast) when I try to perform this:
...
Map<? estends SomeType, SomeOtherType> map;
...
Map<SomeType, SomeOtherType> castedMap = (Map<SomeType, SomeOtherType>) map;
...
I mean what is the danger of publishing castedMap to an outside code?
Both opperations will work perfectly at runtime:
- getting elements from castedMap using key of type SomeType
- putting elements in castedMap using key of type SomeType.
I would simply suppress warnings using @SuppressWarnings("unchecked").
As boring as the answer may be: When there is a warning, then it's not type-safe. That's it.
Why it is not type safe can be seen in this example:
import java.util.HashMap;
import java.util.Map;
class SomeType {}
class SomeSubType extends SomeType {}
class SomeOtherType {}
public class CastWarning
{
public static void main(String[] args)
{
Map<SomeSubType, SomeOtherType> originalMap = new HashMap<SomeSubType, SomeOtherType>();
Map<? extends SomeType, SomeOtherType> map = originalMap;
Map<SomeType, SomeOtherType> castedMap = (Map<SomeType, SomeOtherType>) map;
// Valid because of the cast: The information that the
// key of the map is not "SomeType" but "SomeSubType"
// has been cast away...
SomeType someType = new SomeType();
SomeOtherType someOtherType = new SomeOtherType();
castedMap.put(someType, someOtherType);
// Valid for itself, but causes a ClassCastException
// due to the unchecked cast of the map
SomeSubType someSubType = originalMap.keySet().iterator().next();
}
}