Why am I losing type information?

前端 未结 2 1012
挽巷
挽巷 2021-01-13 07:28

I have found something interesting to happen with Maps, rawtypes and generics. Following code:

static {
          Map map = new HashMap ();
          Set &l         


        
2条回答
  •  余生分开走
    2021-01-13 08:25

    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.

提交回复
热议问题