Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics cast issue

Tags:

java

generics

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'.

like image 696
Victor Sorokin Avatar asked Nov 11 '11 12:11

Victor Sorokin


People also ask

Do generics prevent type cast errors?

Implementing generics into your code can greatly improve its overall quality by preventing unprecedented runtime errors involving data types and typecasting.

Can you cast generic type Java?

The Java compiler won't let you cast a generic type across its type parameters because the target type, in general, is neither a subtype nor a supertype.

How do you avoid ClassCastException?

To prevent the ClassCastException exception, one should be careful when casting objects to a specific class or interface and ensure that the target type is a child of the source type, and that the actual object is an instance of that type.

What does class <?> Mean in Java?

What Does Class Mean? A class — in the context of Java — is a template used to create objects and to define object data types and methods. Classes are categories, and objects are items within each category. All class objects should have the basic class properties.


2 Answers

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);
like image 94
millimoose Avatar answered Sep 28 '22 12:09

millimoose


This will compile:

List<Class<? extends A>> numbers = Arrays.<Class<? extends A>>asList(B.class);
like image 39
H-Man2 Avatar answered Sep 28 '22 14:09

H-Man2