Datasheet

}
public static void main(String args[])
{
CustomHolder2<String> stringHolder = new CustomHolder2<String>();
CustomHolder2<Object> objectHolder = new CustomHolder2<Object>();
String str = new String(“test string”);
String str2;
stringHolder.putItem(str);
objectHolder.putItem(str);
//processHolderObject(stringHolder);
processHolderObject(objectHolder);
processHolderString(stringHolder);
//processHolderString(objectHolder);
processHolderWildcard(stringHolder);
processHolderWildcard(objectHolder);
}
The two lines that are commented will prevent the program from compiling. If both these lines are
uncommented, the compiler issues the following errors:
c:\>javac CustomHolder2.java
CustomHolder2.java:48: processHolderObject(CustomHolder2<java.lang.Object>) in C
ustomHolder2<E> cannot be applied to (CustomHolder2<java.lang.String>)
processHolderObject(stringHolder);
^
CustomHolder2.java:52: processHolderString(CustomHolder2<java.lang.String>) in C
ustomHolder2<E> cannot be applied to (CustomHolder2<java.lang.Object>)
processHolderString(objectHolder);
^
2 errors
This reminds you that the type parameter used must match the formal type parameter. However, notice
that neither line that invokes
processHolderWildcard is commented. This is because using the wild-
card allows you to pass in either
stringHolder or objectHolder. You can read the method parameter
type
CustomerHolder2<?> as “a CustomHolder2 of any type” as opposed to “of Object type” or “of
String type.”
A type parameter can be restricted to certain types by what is called a bound. A bound can be applied to
a regular type parameter or a wildcard. Revisit the
Shape example from earlier in the chapter, which
defines a
Shape interface:
import java.util.ArrayList;
import java.util.Iterator;
interface Shape {
void draw();
12
Part I: Thinking Like a Java Developer
05_777106 ch01.qxp 11/28/06 10:43 PM Page 12