Reputation: 31
While trying to understand java generic types and usage of wild card "?", I tried the following:
List<?> li = new ArrayList<Integer>();
List<Integer> li2 = new ArrayList<Integer>();
li2.add(new Integer(6));
li = li2;
The above compiles and runs fine. But if I try:
li.add(new Integer(5));
I get following compilation error (using Oracle JDeveloper as IDE):
Error(24,9): cannot find method add(java.lang.Integer)
Why does the above not compile but the assignment li=li2
is fine? Also if I want to call li.add(...)
what is an acceptable parameter value?
Upvotes: 2
Views: 120
Reputation: 11662
A call to "li" will not bother whether you assigned it an ArrayList<Integer>
or a LikedList<String>
, it will work only on the declared type, that is List<?>
.
When you declare a generic parameter, it can be applied to return types and to method arguments. For example, in a List<String>
, you will have a String get(int i)
and a void add(String)
methods.
Both are safe, cause with this methods you can only add (and retrieve) String's from the list.
On a List<?>
you will have a Object get(int i)
method, because whatever is in the list it can safely be cast to Object, be it Integer or String.
However, offering a void add(Object)
method, is unsafe, cause would permit you to add a String to an Integer list or vice versa (or any other thing).
Upvotes: 2
Reputation: 9402
?
is a wildcard type, encompassing all reference types. Values that are going to be assigned to the type ?
must be assignable to any reference type. Integer
is not assignable to all reference types (for example, String s = new Integer(1);
fails). In fact, in Java the only value assignable to all reference types is null
, which is the only value you can add to List<?>
Other fun combinations:
? super Number
is a range including types Object
and Number
. When you write such a value, it has to be both Object
and Number
, ie. Integer
would be okay. When reading such a value, it will be either Object
or Number
(so, Object
).
? extends Number
is a range including types Number
and all its subtypes. When you write such a value, it has to be of a type of all subtypes of Number, ie. it has to be null
. When reading such a value, it will be a Number
.
Upvotes: 3