Craig Chan
Craig Chan

Reputation: 31

Using java generic types with wild card "?"

While trying to understand java generic types and usage of wild card "?", I tried the following:

  1. List<?> li = new ArrayList<Integer>();
  2. List<Integer> li2 = new ArrayList<Integer>();
  3. li2.add(new Integer(6));
  4. 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

Answers (2)

Simone Gianni
Simone Gianni

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

Karol S
Karol S

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

Related Questions