«^»
11.3 Using a parameterized type for a parameter

The type List<Shape> can be used just like any other type. So we can produce methods that have this as their return type, or a method that has this as the type of one of its parameters:

0860:    private static void printList1(List<Shape> pList)
0861:    {
0862:       Iterator<Shape> tIterator = pList.iterator();
0863:       while (tIterator.hasNext())
0864:       {
0865:          Shape tShape = tIterator.next();
0866:          System.out.println("X is " + tShape.getX());
0867:       }
0868:    }

However, with Java 5, many of the uses of Iterator should be replaced by a foreach statement. So the above can be simplified to:

0869:    private static void printList2(List<Shape> pList)
0870:    {
0871:       for (Shape tShape : pList)
0872:       {
0873:          System.out.println("X is " + tShape.getX());
0874:       }
0875:    }

Things get interesting when you want to write a method that works for any homogeneous list: a list of shapes, a list of strings, and so on. The new notation:

List<?>
has to be used: it means a List where each element is of some unknown type. Here it is in action:
0876:    private static void printList3(List<?> pList)
0877:    {
0878:       Iterator<?> tIterator = pList.iterator();
0879:       while (tIterator.hasNext())
0880:       {
0881:          Object tObject = tIterator.next();
0882:          System.out.println(tObject);
0883:       }
0884:    }

Once again, this can be simplified to:

0885:    private static void printList4(List<?> pList)
0886:    {
0887:       for (Object tObject : pList)
0888:       {
0889:          System.out.println(tObject);
0890:       }
0891:    }

Suppose instead you want to provide a method that works only for a List where the element type is the type Shape or any of its subclasses. You may be tempted to use one of the methods given earlier, a method that has a parameter of type List<Shape>. However, a class that implements the interface List<Circle> cannot be used as an argument to this method. Instead we can use:

0892:    private static void printList5(List<? extends Shape> pList)
0893:    {
0894:       for (Shape tShape : pList)
0895:       {
0896:          System.out.println("X is " + tShape.getX());
0897:       }
0898:    }
This can be used with an object of a class that implements List<Shape>, an object of a class that implements List<Circle>, and so on.