Victor Sorokin
Victor Sorokin

Reputation: 11996

Generics cast issue

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

Answers (6)

millimoose
millimoose

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

Kowser
Kowser

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

H-Man2
H-Man2

Reputation: 3189

This will compile:

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

Upvotes: 5

Buhake Sindi
Buhake Sindi

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

Bohemian
Bohemian

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

S2S2
S2S2

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

Related Questions