Reputation: 11996
Here's my issue: given these classes
class A {}
class B extends A {}
This code compiles:
List<Class<? extends A>> list = Arrays.asList(B.class, A.class);
And this does not:
List<Class<? extends A>> anotherList = Arrays.asList(B.class);
What gives?
UPDATE: This code compiles in Java 8. Apparently, due to 'Improved Type Inference'.
Upvotes: 17
Views: 737
Reputation: 39950
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);
Upvotes: 14
Reputation: 8261
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.
Upvotes: 1
Reputation: 3189
This will compile:
List<Class<? extends A>> numbers = Arrays.<Class<? extends A>>asList(B.class);
Upvotes: 5
Reputation: 89169
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
).
Upvotes: 2
Reputation: 424983
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));
Upvotes: 1
Reputation: 8502
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?
Upvotes: 0