Consider following methods:
public static void listAll(LinkedList list) {
for(Object obj : list)
System.out.println(obj);
}
and
public static void listAll(LinkedList<?> list) {
for(Object obj : list)
System.out.println(obj);
}
What is the difference between these two methods? If there is no difference, why we should use the second one?
<?>
doesn't allow you to add objects in list. See the program below. It is specific type of list we have passed to method <?>
.
Specific means, list was created with specific type and passed to <?>
method listAll
. Don't confuse with word specific
.
Specific can be any normal object, like, Dog, Tiger, String, Object, HashMap, File, Integer, Long.... and the list is endless.
JLS
forces <?>
method for not to perform add any irrelevant objects
in called <?>
method once you have defined (defined in calling method not in called-listAll
) list containing specific type
of object.
It is like <?>
saying "don't touch me".
public static void listAll(LinkedList list)
{
list.add(new String()); //works fine
for(Object obj : list)
System.out.println(obj);
}
public static void listAll(LinkedList<?> list)
{
list.add(new String()); //compile time error. Only 'null' is allowed.
for(Object obj : list)
System.out.println(obj);
}
Now let's look at the different scenario. What will happen when we declare specific type like, Dog, Tiger, Object, String ..... anything. Let's change the method to specific type
.
public static void listAll(LinkedList<String> list)// It is now specific type, 'String'
{
list.add(new String());//works fine. Compile time it knows that 'list' has 'String'
for(Object obj : list)
System.out.println(obj);
}
List
is a raw type, List<?>
is a generic type with wildcard argument.
Suppose that we have the following variables:
List<?> a;
List<String> b;
List c;
The assignment b=a
gives a compile-time error (a List<String>
is not assignable to List<?
), but c=a
compiles fine (List<String>
is assignable to the raw type List
for compatibility with legacy code not using generics).
The assignment b=c
gives a compile-time warning (List<?>
is not assignable to List<String>
), but a=c
compiles fine (List<String>
is assignable to List<?>
)