Reputation: 3882
Following application produce compilation error in line (*)
ArrayList<?> l = new ArrayList<>();
l.add(new Integer(1));
compilation error says:
error: no suitable method found for add(C<CAP#1>)
l.add(o);
Why is that? I thought List should accept anything
Upvotes: 1
Views: 149
Reputation: 7166
I generally prefer not to use wildcards. These are the options:
Using a List is for a list with an unknown type:
List<?> list = Arrays.asList(1, 2d, "3"); // can contain any Object
for (Object obj : list) { // you can retrieve them
System.out.println("--> " + obj);
}
list.add("a"); // compile error
Using <? extends Number>
lets you retrieve numbers from a list, but you still can't add anything:
List<? extends Number> list2 = Arrays.asList(1, 2, 3); // can contain any number
for (Number n : list2) {
System.out.println("--> " + n);
}
list2.add(5); // compile error
List<? extends Number> list3 = Arrays.asList(1, 2d, 3F); // can contain any number
for (Number n : list3) {
System.out.println("--> " + n);
}
list3.add(5); // compile error
The opposite of <? extends ...>
is <? super ...>
. This looks weird. The point is that callers of such List<>
can add stuff of the appropriate type. Retrieving is a problem though:
List<? super Integer> list4 = new ArrayList<>();
list4.add(1);
for (Integer num : list4) { } // compile error
for (Object num : list4) { } // this is fine, but not that useful
If you want a flexible data structure, you can use the right supertype. Say for instance, a List<Number>
is quite flexible. If you really need to, you can use bound types like List<T extends Number>
. You can read more about that at this answer.
Upvotes: 0
Reputation: 206786
You misunderstood what List<?>
means.
It does not mean: a List
of any kind of object, so that you should be able to add anything to the List
(it is not the same as a raw List
or a List<Object>
).
It means: a List
of a specific, but unknown type. Because the type is unknown, you cannot add anything to the list - the compiler doesn't know what the exact type of the objects in the list should be, so it cannot check if you're not trying to put something into the list that should not be allowed, so it doesn't allow you to add anything to the list.
Upvotes: 5