The idea behind this is that List<?>
represents a generic List
of some unknown type. This List<?>
could be List<String>
, List<Double>
, List<File>
, or anything really, all of which count as List<?>
. This means if you have a variable of type List<?>
, you can't just add a Double
to it, because myListOfWildcard.add(someDouble)
would fail if myListOfWildcard
is actually a List<String>
, which it could be.
The wildcards (in particular, List<?>
) aren't as useful for lists that you want to be able to contain anything. For those you generally want to use List<Object>
. A wildcard would be more useful if you want to allow yourself these special cases. If you have a method and you want it to be able to accept any type of list whether it be List<String>
or List<Double>
, this is what List<?>
is useful for, because any of these is a List<?>
. However, you lose the ability to assume anything about the actual generic type parameter of the list, which means you can't just add a Double
.
List<?>
is a shortcut for List<? extends Object>
. Wildcard lists are mostly useful as the arguments for a method; you usually don't want to create them yourself. Collection.containsAll is a good real world example of their use: In particular, Collection.containsAll
accepts any Collection
as its argument. It doesn't have to be a Collection<Object>
, but it would if Collection<Object>
where listed as its type instead of Collection<?>
.
Edit: Added paragraphs from comments.