Java Reference
In-Depth Information
Introduction to Generics
If we want to build a collection of Shape instances, we can use a List to hold them,
like this:
List shapes = new ArrayList (); // Create a List to hold shapes
// Create some centered shapes, and store them in the list
shapes . add ( new CenteredCircle ( 1.0 , 1.0 , 1.0 ));
// This is legal Java—but is a very bad design choice
shapes . add ( new CenteredSquare ( 2.5 , 2 , 3 ));
// List::get() returns Object, so to get back a
// CenteredCircle we must cast
CenteredCircle c = ( CentredCircle ) shapes . get ( 0 );
// Next line causes a runtime failure
CenteredCircle c = ( CentredCircle ) shapes . get ( 1 );
A problem with this code stems from the requirement to perform a cast to get the
shape objects back out in a usable form—the List doesn't know what type of objects
it contains. Not only that, but it's actually possible to put different types of objects
into the same container—and everything will work fine until an illegal cast is used,
and the program crashes.
m
e
What we really want is a form of List that understands what type it contains. Then,
javac could detect when an illegal argument was passed to the methods of List and
cause a compilation error, rather than deferring the issue to runtime.
Java provides syntax to cater for this—to indicate that a type is a container that
holds instances of another reference type we enclose the payload type that the con‐
tainer holds within angle brackets:
// Create a List-of-CenteredCircle
List < CenteredCircle > shapes = new ArrayList < CenteredCircle >();
// Create some centered shapes, and store them in the list
shapes . add ( new CenteredCircle ( 1.0 , 1.0 , 1.0 ));
// Next line will cause a compilation error
shapes . add ( new CenteredSquare ( 2.5 , 2 , 3 ));
// List<CenteredCircle>::get() returns a CenteredCircle, no cast needed
CenteredCircle c = shapes . get ( 0 );
This syntax ensures that a large class of unsafe code is caught by the compiler,
before it gets anywhere near runtime. This is, of course, the whole point of static
type systems—to use compile-time knowledge to help eliminate whole swathes of
runtime problems.
Container types are usually called generic types —and they are declared like this:
Search WWH ::




Custom Search