Section 2.2. Wildcards with extends


2.2. Wildcards with extends

Another method in the Collection interface is addAll, which adds all of the members of one collection to another collection:

 interface Collection<E> {   ...   public boolean addAll(Collection<? extends E> c);   ... } 

Clearly, given a collection of elements of type E, it is OK to add all members of another collection with elements of type E. The quizzical phrase "? extends E" means that it is also OK to add all members of a collection with elements of any type that is a subtype of E. The question mark is called a wildcard, since it stands for some type that is a subtype of E.

Here is an example. We create an empty list of numbers, and add to it first a list of integers and then a list of doubles:

 List<Number> nums = new ArrayList<Number>(); List<Integer> ints = Arrays.asList(1, 2); List<Double> dbls = Arrays.asList(2.78, 3.14); nums.addAll(ints); nums.addAll(dbls); assert nums.toString().equals("[1, 2, 2.78, 3.14]"); 

The first call is permitted because nums has type List<Number>, which is a subtype of Collection<Number>, and ints has type List<Integer>, which is a subtype of Collection<? extends Number>. The second call is similarly permitted. In both calls, E is taken to be Number. If the method signature for addAll had been written without the wildcard, then the calls to add lists of integers and doubles to a list of numbers would not have been permitted; you would only have been able to add a list that was explicitly declared to be a list of numbers.

We can also use wildcards when declaring variables. Here is a variant of the example at the end of the preceding section, changed by adding a wildcard to the second line:

 List<Integer> ints = Arrays.asList(1,2); List<? extends Number> nums = ints; nums.add(3.14);  // compile-time error assert ints.toString().equals("[1, 2, 3.14]");  // uh oh! 

Before, the second line caused a compile-time error (because List<Integer> is not a subtype of List<Number>), but the third line was fine (because a double is a number, so you can add a double to a List<Number>). Now, the second line is fine (because List<Integer> is a subtype of List<? extends Number>), but the third line causes a compile-time error (because you cannot add a double to a List<? extends Number>, since it might be a list of some other subtype of number). As before, the fourth line shows why one of the preceding lines is illegal!

In general, if a structure contains elements with a type of the form ? extends E, we can get elements out of the structure, but we cannot put elements into the structure. To put elements into the structure we need another kind of wildcard, as explained in the next section.




Java Generics and Collections
Java Generics and Collections
ISBN: 0596527756
EAN: 2147483647
Year: 2006
Pages: 136

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net