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

I read several topics that cover some questions about generics, such as their association with raw types . But I would like some further explanation on a specific line found in the Java SE tutorial on unrelated generalizations .

According to the proposal:

The purpose of printList is to print a list of any type, but it does not achieve this goal - it only prints a list of instances of Object; it cannot print List <Integer>, List <String>, List <Double>, and so on, because they are not subtypes of List <Object>.

If I understand this sentence well; the difference between List<?> and List<Object> is that we can use an argument of type List<String> or List<Integer> by implementing the first. Although, if we implement later, we can only use an argument of type List<Object> . As if List<?> Is the upper bound of Object , namely List<? Object> List<? Object> .

But then the following sentence confuses me in the sense that according to what I understood earlier, the List<Object> should contain only instances of the Object class, and not something else.

It is important to note that List<Object> and List<?> Do not match. You can insert an object or any subtype of an object into a List<Object> . But you can insert null into List<?> .

+6
source share
2 answers

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

However, this method:

 public void print(List<Number> list); 

actually only take a List , which is exactly List<Number> . It will not accept the list declared by List<Integer> .

Thus, the difference List<?> Will accept any list with any declaration, but List<Object> will only take something that was declared as List<Object> , nothing more.

The last quote simply states that List<?> Is a list for which you literally don't know in what type its elements are. Because of this, you cannot add anything but null .

+10
source

The sentence that confuses you is trying to warn you that although List<?> Is a supertype of all shared lists, you cannot add anything to the 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 does not compile because you cannot add anything but null to List<?> . (This is what the sentence is trying to tell you.)

addObjectToList2 compiles, but calling it in main() does not compile, because List<Object> not a supertype of List<String> .

addObjectToList3 compiles and calls. This is a way to add items to the general list.

+7
source

All Articles