Up to the release of Java 1.5, this is all that you needed to know about the collections. They
were a set of interfaces and implementations that added most of the usual ways of gathering
objects together to the standard libraries. Using them was simple, easy, and saved everyone
a lot of time. But all that changed with Java 1.5 and the introduction of parameterized types.
This was a general change to the language, but the greatest impact with respect to the libraries
occurs in the collections. If you are not using a version of Java beyond 1.4, you can stop read-
ing this chapter now. But for the rest of you (and I'm assuming that this is just about every-
one), let's continue on to see what parameterized types and generics are and what they do to
The motivation for the introduction of parameterized types can be seen in our last example,
when we were using our Set of Players to print out a team roster. As we iterated through the
Set of Player objects on a team, we had to perform a class cast on the object returned from
the next() method, as seen in the line:
p = (Player)e.next();
This is, in some sense, an unsafe operation. Even though the only way we know of to put an
object into the List that is return from the getRoster() method on a Team object is to call the
addPlayer() method on the Team object, and even though the type of object that is passed in
to the addPlayer() method is checked, it is certainly logically possible that something other
than a Player object can be inserted into the List , perhaps in some method we know nothing
about. Certainly, if the getRoster() method returned a reference to the players field rather
than a copy, we would have no guarantees of what had been inserted into the Set . And if an
object that is not a Player is inserted into the List , the casting of the result of the next()
operation on the iterator will fail.
Of course, there are mechanisms in Java that would let us write code to deal with the failure.
We could check, before the cast, to make sure that the object returned from the iterator was ac-
tually an instanceof the Player type. And the cast operation in the Java language is checked.
This means that unlike casting in C or C++, where a cast in an assertion that the area of
memory referred to should be treated as a particular data type (whether it is or not), an attempt
to cast an object in Java into some type different from the object's true type results in throw-
ing a Runtime exception. If no one catches this exception, then the program will terminate,