Warning when performing cast with generic types

2020-04-11 06:45发布

问题:

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").

回答1:

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();
    }
}


标签: java generics