Using Parameterized References to Call Set and Get Methods
Generic classes are suitable for implementing ADTs called collections (also called containers) where the element type is usually specified by a type parameter. The Java Collections Framework is a prime example of such collections. A collection usually provides two basic operations: a set operation (also called a write or put operation) to add an element to the collection, and a get operation (also called a read operation) to retrieve an element from the collection. The set operation takes a parameter of the type T, where T is a type parameter of the generic class. The get operation returns a value of the type parameter T. The class Node<E> provides these two basic operations to manipulate the data in a node:
class Node<E> {
private E data;
// …
public void setData(E obj) { data = obj; } // (1) Set operation.
public E getData() { return data; } // (2) Get operation.
// …
}
So far we have called these two methods using references of concrete parameterized types:
Node<Number> numNode = new Node<>(2020, null);
numNode.setData(2021); // (3) Can only set a Number.
Number data = numNode.getData(); // (4) Can only get a Number.
The actual type parameter in the above method calls is a concrete type, but what happens when we use a reference of a wildcard parameterized type that represents a family of types? For example, what if the type of the reference numNode is Node<? extends Number>? Is the method call at (3) type-safe? Is the assignment at (4) type-safe? Operations that can potentially break the type-safety are flagged as either compile-time errors or warnings. If there are warnings but no errors, the program still compiles. However, type-safety at runtime is not guaranteed.
The key to using generics in Java is understanding the implications of wildcard parameterized types in the language—and why the compiler will not permit certain operations involving wildcards, since these might break the type-safety of the program. To illustrate some of the subtleties, we compile the class in Example 11.7 successively with different headers for the method checkIt(). The parameter type is different in each method header, from (h1) to (h5). The method uses three local variables object, number, and integer of type Object, Number, and Integer, respectively ((v1) to (v3)). There are three calls to the setData() method of the generic class Node<E> to set an Object, a Number, and an Integer as the data in the node referenced by the reference s0 ((s1) to (s3)). There are also three calls to the getData() method of the generic class Node<E>, assigning the return value to each of the local variables ((s4) to (s6)). And finally, the last statement, (s7), tests whether the data retrieved can be put back in again.
Example 11.7 Illustrating Get and Set Operations Using Parameterized References
class WildcardAccessRestrictions {
static void checkIt(Node s0) { // (h1)
//static void checkIt(Node<?> s0) { // (h2)
//static void checkIt(Node<? extends Number> s0) { // (h3)
//static void checkIt(Node<? super Number> s0) { // (h4)
//static void checkIt(Node<Number> s0) { // (h5)
// Local variables
Object object = new Object(); // (v1)
Number number = 1.5; // (v2)
Integer integer = 10; // (v3)
// Method calls
s0.setData(object); // (s1)
s0.setData(number); // (s2)
s0.setData(integer); // (s3)
object = s0.getData(); // (s4)
number = s0.getData(); // (s5)
integer = s0.getData(); // (s6)
s0.setData(s0.getData()); // (s7)
}
}
Attempts to compile the method in Example 11.7 with different headers are shown in Table 11.2. The rows are statements from (s1) to (s7) from Example 11.7. The columns indicate the type of the parameter s0 in the method headers (h1) to (h5). The reference s0 is used to call the methods. The entry ok means the compiler did not report any errors or any unchecked warnings. The entry ! means the compiler did not report any errors but issued an unchecked call warning. The entry × means the compiler reported an error. In other words, we cannot carry out the operations that are marked with the entry ×.
Table 11.2 Get and Set Operations Using Parameterized References

Leave a Reply