Generics cast issue

后端 未结 6 1158
悲哀的现实
悲哀的现实 2021-01-01 17:00

Here\'s my issue: given these classes

class A {}
class B extends A {}

This code compiles:

    List

        
相关标签:
6条回答
  • 2021-01-01 17:40

    Damn good question, and I don't know the answer, but here's a work around:

    List<Class<? extends A>> numbers = new ArrayList<Class<? extends A>>(Arrays.asList(B.class));
    
    0 讨论(0)
  • 2021-01-01 17:41
    Arrays.asList(B.class);
    

    is generified as

    List<Class<B>> numbers = Arrays.asList(B.class);
    

    Since it has only 1 attribute of type T that match the parameterized type (in this case, B.class).

    0 讨论(0)
  • 2021-01-01 17:44

    This is a problem of Covariance/Contravariance in Generics. The following SO question should help you understand and solve the problem:

    Demonstrate covariance and contravariance in Java?

    How would contravariance be used in Java generics?

    0 讨论(0)
  • 2021-01-01 17:47

    This will compile:

    List<Class<? extends A>> numbers = Arrays.<Class<? extends A>>asList(B.class);
    
    0 讨论(0)
  • 2021-01-01 18:00

    Just to add, we can rewrite the code as below

    List<Class<? extends A>> asListA = Arrays.asList(B.class, A.class);
    List<Class<B>> asListB = Arrays.asList(B.class);
    
    List<Class<? extends A>> numbers = asListA;
    List<Class<? extends A>> numbers2 = asListB; // it will fail here
    

    And @Inerdia explained the details already.

    0 讨论(0)
  • 2021-01-01 18:05

    In the first example, the inferred type of the Arrays.asList() call is List<Class<? extends A>>, which is obviously assignable to a variable of the same type.

    In the second example, the type of the right side is List<Class<B>>. While Class<B> is assignable to Class<? extends A>, List<Class<B>> is not assignable to List<Class<? extends A>>. It would be assignable to List<? extends Class<? extends A>>.

    The reason for this is the same one as why a List<B> isn't assignable to List<A>. If it was, it would make the following (not-typesafe) code possible:

    List<Class<B>> bb = new ArrayList<B>();
    List<Class<? extends A>> aa = bb;
    aa.add(A.class);
    
    0 讨论(0)
提交回复
热议问题