Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java wildcard difference in 7 and 8

Tags:

java

generics

I have the following code, which works fine on Java 8:

List<Class<?>> KEY_NAME_CLASSES = Collections.singletonList(String.class);

But when I try to use the Java 7 compiler, I get an error:

incompatible types: java.util.List<java.lang.Class<java.lang.String>> cannot be converted to java.util.List<java.lang.Class<?>>

Why? Is there some way to use such wildcards in Java 7?

like image 385
Vasiliy Pispanen Avatar asked Aug 04 '16 10:08

Vasiliy Pispanen


People also ask

What is wildcard in Java?

The question mark (?) is known as the wildcard in generic programming. It represents an unknown type. The wildcard can be used in a variety of situations such as the type of a parameter, field, or local variable; sometimes as a return type.

What is a lower bounded wildcard?

The Upper Bounded Wildcards section shows that an upper bounded wildcard restricts the unknown type to be a specific type or a subtype of that type and is represented using the extends keyword. In a similar way, a lower bounded wildcard restricts the unknown type to be a specific type or a super type of that type.

What is the difference between generics and wildcards in Java?

Wildcards are nothing but the question mark(?) that you use in the Java Generics. We can use the Java Wildcard as a local variable, parameter, field or as a return type. But, when the generic class is instantiated or when a generic method is called, we can't use wildcards.

What is the difference between bounded and unbounded wildcards in Java generics?

both bounded and unbounded wildcards provide a lot of flexibility on API design especially because Generics is not covariant and List<String> can not be used in place of List<Object>. Bounded wildcards allow you to write methods that can operate on Collection of Type as well as Collection of Type subclasses.


1 Answers

Type inference differs significantly in Java-7 and Java-8. In short, to determine the expression type Java-7 uses only the expression itself while Java-8 can use the surrounding context. So the type of the expression Collections.singletonList(String.class) in Java-7 is the most precise type which could be determined from this expression, namely List<Class<String>>. Java-8 is smarter: it also looks that this expression is assigned to another yet compatible type List<Class<?>>, so it sets the type of Collections.singletonList(String.class) to List<Class<?>> as well.

To make this code working in Java-7 you should specify the generic type explicitly:

List<Class<?>> KEY_NAME_CLASSES = Collections.<Class<?>>singletonList(String.class);
like image 61
Tagir Valeev Avatar answered Oct 11 '22 23:10

Tagir Valeev