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?
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.
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.
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.
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With