THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

new SingleLinkQueue();
queue.add("Hello");
queue.add("World");


Now there is no need for a cast when invoking remove:


String hello = queue.remove();


Nor is it possible to add the wrong kind of element to the queue:


queue.add(25); // INVALID: won't compile


Generic types are invaluable in defining these kind of collection classes, as you'll see in Chapter 21, but they
have uses in many other situations.


11.1. Generic Type Declarations


The declaration of the class Cell is an example of a generic type declaration. It declares Cell to be a
generic class, where the type variable E is known as the type parameter of the generic declaration. When you
use a type name such as Cell, providing a specific type argument (String) to replace the
generic type parameter (E), you thereby introduce a parameterized type. This has some similarities to the
method invocation process where declared parameters are given the values of specific arguments, so the use
of a parameterized type such as Cell is also known as a generic type invocation.


A generic type declaration can contain multiple type parameters, separated by commas. For example, the Map
interface (see page 587) defines a generic mapping between keys and values so it is declared as
interfaceMap<K,V>, where K is the type parameter for the key type and V is the type parameter for the
value type.


When you define a generic class, all invocations of that generic class are simply expressions of that one class.
Declaring a variable strCell as Cell tells the compiler that strCell will refer to an object
of type Cell where E will be String. It does not tell the compiler to create a new class
Cell. Cell and Cell are not two separate classes. They are two
generic type invocations of the one classCellthat are applied in two different ways to two different objects.
The class Cell is known as the raw type corresponding to the generic class declaration Cell.


The following code shows quite clearly that there is just one class because the value of same is TRue:


Cell strCell = new Cell("Hello");
Cell intCell = new Cell(25);
boolean same = (strCell.getClass() == intCell.getClass());


This may seem surprising if you thought that Cell was a class. But it is only Cell that is a class.
The use of and in the constructor invocations are not class definitions. They declare
information about the type of object being constructed so that the compiler can check that the object is used
correctly. At runtime, no generic type information is present in objects. In the example above, the Cell
object that contains the element "Hello" has no knowledge that it was constructed as a

Free download pdf