3

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?

Sam R.
  • 16,027
  • 12
  • 69
  • 122
Sina Barghidarian
  • 450
  • 1
  • 4
  • 18

2 Answers2

6

<?> 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);
}
AmitG
  • 10,365
  • 5
  • 31
  • 52
  • > does not allow to set objects in list, but we can get objects right? what's the type of objects we get (in a getter() method? is it object or type parameter bounds? – Sina Barghidarian Mar 20 '13 at 09:24
  • It is Object type always. Generic is all for convenience. It takes care of programmar not to mislead the coding. Otherwise programmer will find mess in run-time. – AmitG Mar 20 '13 at 09:43
  • 1
    @CenaPi You should look up the "PECS" mechanism as described by Joshua Bloch in "Effective Java". "Producer Extends, Consumer Super". A wildcard > is synonymous to extends Object>, so "extends", thus a "producer". A "producer" means you can get things out of the list, but not add to it. – Timmos Dec 17 '13 at 16:54
  • @SinaBarghidarian In that case you can add any `Foo` object. `((List super Foo>) new LinkedList<>()).add(new Foo());` – Kröw Oct 11 '18 at 17:54
1

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<?>)

Javier
  • 12,100
  • 5
  • 46
  • 57