Implications of Using Wildcards


The downside of using a wildcard on a reference is that you cannot call methods on it that take an object of the type parameter. For example, suppose you create a pad utility method that can add an element n times to the end of a list.

 package sis.util; import java.util.*; import junit.framework.*; public class ListUtilTest extends TestCase {    public void testPad() {       final int count = 5;       List<Date> list = new ArrayList<Date>();       final Date element = new Date();       ListUtil.pad(list, element, count);       assertEquals(count, list.size());       for (int i = 0; i < count; i++)          assertEquals("unexpected element at " + i,             element, list.get(i));    } } 

The pad method declares the list parameter to be a List that can be bound to any type:

 package sis.util; import java.util.*; public class ListUtil {    public static void pad(List<?> list, Object object, int count) {       for (int i = 0; i < count; i++)          list.add(object);    } } 

The error you receive indicates that the compiler doesn't recognize an appropriate add method.

 cannot find symbol symbol  : method add(java.lang.Object) location: interface java.util.List<?>          list.add(object);              ^ 

The problem is that the wildcard ? designates an unknown type. Suppose that the List is bound to a Date:

 List<Date> list = new ArrayList<Date>(); 

Then you attempt to pass a String to the pad method:

 ListUtil.pad(list, "abc", count); 

The pad method doesn't know anything about the specific type of the object being passed in, nor does it know anything about the type to which the list is bound. It can't guarantee that a client isn't trying to subvert the type safety of the list. Java just won't allow you to do this.

There is still a problem even if you specify an upper bound on the wildcard.

 public static void pad(       List<? extends Date> list, Date date, int count) {    for (int i = 0; i < count; i++)       list.add(date);  // this won't compile } 

The problem is that a client could bind the list to java.sql.Date:

 List<java.sql.Date> list = new ArrayList<java.sql.Date>(); 

Since java.util.Date is a superclass ofjava.sql.Date, you cannot add it to a list that is constrained to hold only objects of type java.sql.Date or a subclass of java.sql.Date. Due to erasure, Java has no way of figuring out whether or not a given operation is safe, so it must prohibit them all. The general rule of thumb is that you can use bounded wildcards only when reading from a data structure.



Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

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