Reputation: 319
What is the difference between List
and List<?>
? I know I can't add any element 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 compile time error. So is there any difference in these two approaches?
Upvotes: 6
Views: 209
Reputation: 7448
The second method uses generics (introduced in Java 5).
One important distinction is the <?>
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, as you'd be able to add any object to your List. Although, you'll get a (compiler) warning that you declaration should be parameterized.
Using the <?>
unbounded wildcard syntax will avoid the warning, but you're telling the compiler it could be a list of any type, instead of actually using generics to enforce type safety. You are strongly encouraged to use generics to assist you in making your application type safe.
If, for example, you know that the list should only ever contain String objects, declare it thus:
List<String> myList
Then you'll avoid unnecessary casting of use of the instanceof
operator, etc.
Here's a brief tutorial on generics in Java, for your information:
http://javarevisited.blogspot.co.uk/2011/09/generics-java-example-tutorial.html
Upvotes: 0
Reputation: 370415
Just writing List
without a type parameter is deprecated, but otherwise the same as writing List<Object>
. So the question becomes "What's the difference between List<Object>
and List<?>
and which one should I use?".
As you already know, you can't add (anything other than null
) to a List<?>
, so if you need to add to a list, you should use a List<Object>
(or a more specific type where applicable, of course). On the other hand, a method that takes a List<Object>
, only accepts List<Object>
s and not any lists that contain a subclass of Object
. That is, it would not accept a List<String>
. If the method takes a List<?>
however, it accepts any kind of list. So if you don't need to add to the list, you should use List<?>
as it is more general.
Upvotes: 0
Reputation: 68985
List<?>
(pronounced "collection of unknown")is a collection whose element type matches anything. It's called a wildcard type for obvious reasons.
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 don't know what the element type of myListNew stands for, we cannot add objects to it. The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type.
On the other hand, given a List<?>
, we can call get() and make use of the result. The result type is an unknown type, but we always know that it is an object. It is therefore safe to assign the result of get() to a variable of type Object or pass it as a parameter where the type Object is expected.
Upvotes: 1
Reputation: 111359
The difference is that you can't add anything to a List<?>
, since it's a List of an unknown type.
For example, you are prevented from doing this:
List<Integer> listOfInt = new ArrayList<Integer>();
List<?> list = listOfInt;
list.add("hello?"); // Compile-time error
You can add anything you want to the base type List
since the type of the list items is not checked.
Upvotes: 1
Reputation: 49241
Both do the same, but in second case compiler is informed that you really want a list with no type bounds and raises no warnings. If you are working with Java 5 or later you are encouraged to use second approach.
Upvotes: 6
Reputation: 528
Both of them behave same. Using parametrized notation you are just avoiding any warnings in Java5 and above. You cannot have both the syntax in same java file because due to type erasure compiled unit has two methods with exactly same signature in same class file and thus violating language rules. Following is what you would be getting from compiler:
Method processList(List) has the same erasure processList(List) as another method in type ...
Upvotes: 0
Reputation: 8466
List is raw type and List< ?> is wildcard type. Take look http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
Upvotes: 0