List and List <?> In Java
What is the difference between List and List<?> ? I know that I cannot add an item to the List<?> . I have a code:
List<String> myList = new ArrayList<String>(); processList(myList); processListGeneric(myList); public static void processList(List myList) { Iterator it = myList.iterator(); while(it.hasNext()) System.out.println(it.next()); } public static void processListGeneric(List<?> myList) { Iterator<?> it = myList.iterator(); while(it.hasNext()) System.out.println(it.next()); } The name of the two methods cannot be the same, because it causes a compile-time error. So is there a difference in these two approaches?
The difference is that you cannot add anything to the List<?> , Since this is a list of an unknown type.
For example, you are forbidden to do this:
List<Integer> listOfInt = new ArrayList<Integer>(); List<?> list = listOfInt; list.add("hello?"); // Compile-time error You can add whatever you want to the base List type, since the type of the list items is not checked.
List<?> (Pronounced "collection of unknowns") is a collection whose element type corresponds to something. For obvious reasons, it is called a wildcard type. Refer to the following code
List<String> myList = new ArrayList<String>(); myList.add("John"); String name = myList.get(0); System.out.println(name); //print John List<?> myListNew = myList; myListNew.add("Sam");//Compile time error String nameNew = myListNew.get(0);//Compile time error Object newName = myListNew.get(0); System.out.println(newName);//Prints John Since we do not know what the type of the myListNew element means , we cannot add objects to it. The add () method accepts arguments of type E, the type of the item in the collection. When is the actual type parameter ?, it means some unknown type. Any parameter that we pass to add must be a subtype of this unknown type. Since we do not know what it is, we cannot convey anything. The one exception is null, which is a member of each type.
On the other hand, given List<?> , We can call get () and use the result. The result type is an unknown type, but we always know that it is an object. Therefore, it is safe to assign the result of get () to a variable of type Object or to pass it as a parameter in which the type of the object is expected.
The second method uses generics (introduced in Java 5).
One of the important differences is that <?> Represents a single type, not any object like this:
List<? extends Object> myList So, you could say that using the first method (without the wildcard syntax) is more flexible since you can add any object to your list. Although, you will get a warning (compiler) that you should parameterize the declaration.
Using the <?> Syntax of an unlimited wildcard will avoid the warning, but you tell the compiler that it can be a list of any type, instead of actually using generics to ensure type safety. You are strongly encouraged to use generics to help you safely make your type of application.
If, for example, you know that the list should contain only String objects, declare it this way:
List<String> myList Then you will avoid unnecessary use of the instanceof operator, etc.
The following is a short tutorial on generics in Java for your information:
http://javarevisited.blogspot.co.uk/2011/09/generics-java-example-tutorial.html
List is a raw type and List <? > is a wildcard type. Take a look at http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
Both of them behave the same. Using parameterized notation, you simply avoid any warnings in Java5 and above. You cannot have both syntaxes in the same java file because, due to the type, the compiled erase module has two methods with exactly the same signature in the same class file and thus violates language rules. Below you will get from the compiler:
The processList (List) method has the same processList (List) method of the erase process as another method in type ...
It’s just that the List entry without the type parameter is out of date, but otherwise the same as the List<Object> entry. So the question arises: "What is the difference between List<Object> and List<?> And which one should I use?".
As you already know, you cannot add (anything but null ) to the List<?> , So if you need to add to the list, you should use List<Object> (or a more specific type where applicable, of course). On the other hand, a method that accepts a List<Object> accepts only a List<Object> , not any lists containing a subclass of Object . That is, it will not accept List<String> . If the method takes the value List<?> , It takes any kind of list. Therefore, if you do not need to add to the list, you should use List<?> , Since it is more general.