Java generics, Unbound wildcards <?> vs <Object>

There are two separate issues here. A List<Object> can in fact take any object as you say. A List<Number> can take at least Number objects, or of course any subclasses, like Integer.

However a method like this:

public void print(List<Number> list);

will actually only take a List which is exactly List<Number>. It will not take any list which is declared List<Integer>.

So the difference is List<?> will take any List with whatever declaration, but List<Object> will only take something that was declared as List<Object>, nothing else.

The last quote simply states, that List<?> is a list for which you literally don't know what type its items are. Because of that, you can not add anything to it other than null.


The sentence that is confusing you is trying to warn you that, while List<?> is the super-type of all generic lists, you cannot add anything to a List<?> collection.

Suppose you tried the following code:

private static void addObjectToList1(final List<?> aList, final Object o ) {
    aList.add(o);
}

private static void addObjectToList2(final List<Object> aList, final Object o ) {
    aList.add(o);
}

private static <T> void addObjectToList3(final List<T> aList, final T o ) {
    aList.add(o);
}


public static void main(String[] args) {
    List<String> testList = new ArrayList<String>();
    String s = "Add me!";
    addObjectToList1(testList, s);
    addObjectToList2(testList, s);
    addObjectToList3(testList, s);
}

addObjectToList1 doesn't compile, because you cannot add anything except null to a List<?>. (That's what the sentence is trying to tell you.)

addObjectToList2 compiles, but the call to it in main() doesn't compile, because List<Object> is not a super type of List<String>.

addObjectToList3 both compiles and the call works. This is the way to add elements to a generic list.