Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
Consider the following classes (written before the introduction of generics in JDK 5.0), designed to describe various kinds of media that a library might contain:Given the above classes, imagine a program that uses them to catalog information about a collection of books (and only books). Here is a code snippet from that program:public class Library { private List resources = new ArrayList(); public void addMedia(Media x) { resources.add(x); } public Media retrieveLast() { int size = resources.size(); if (size > 0) { return resources.get(size - 1); } return null; } } public class Media { } public class Book extends Media { } public class Video extends Media { } public class Newspaper extends Media { }Type casting the return value from the//A Library containing only Books Library myBooks = new Library(); ... Book lastBook = (Book)myBooks retrieveLast();retrieveLast
method toBook
is necessary, so the compiler knows what kind of object is returned and what kinds of operations can be performed on that object. Even though the programmer may be certain that onlyBook
objects will be returned, the compiler does not know this. If a programming error did result in, say, aVideo
being stored inmyBooks
and then returned here, the cast would cause an unexpected exception to be thrown at runtime.This is the primary reason that generic types and methods (often referred to, simply, as generics) were added to the Java language to add compile-time type checking so the compiler can detect mismatched types at compile time, rather than runtime, when an exception is thrown.
Here is the same
Library
class with a few simple changes (shown in bold), modified to use generics:Library is now a generic type with a single type parameterpublic class Library<E> { private List resources = new ArrayList<E>(); public void addMedia(E x) { resources.add(x); } public E retrieveLast() { int size = resources.size(); if (size > 0) { return resources.get(size - 1); } return null; } } //The Media classes require no changes to use generics //please refer to the original example.E
. When using a generic type, specify a type argument for each of its type parameters. ALibrary
containing onlyBook
objects, for example, would be written asLibrary<Book>
. This is an example of aparameterized type
. The code snippet now looks like this:The type cast and the comment are no longer needed because theLibrary<Book> myBooks = new Library<Book>(); ... Book lastBook = myBooks retrieveLast();Library
instance has been constrained to deal withBook
objects. The compiler now understands that this particular instance ofLibrary
containsBook
s. If the compiler detects that theLibrary
is being used inappropriately trying to add or retrieve aNewspaper
, for example it generates an error.Later on our imaginary program includes the following line of code:
Without generics, the compiler couldn't warn you ifmyBooks.addMedia(myFavoriteBook);myFavoriteBook
is of the wrong type. If it is aString
, for example, a runtime exception would occur somewhere down the road after someone invokesretrieveLast
. These sorts of errors can be especially hard to debug, since the runtime error may occur at a point in the code far removed from the actual programming error that caused it. With generics, the compiler calls out the error right away. You find out about the programming error immediately, and are shown exactly where the problem lies.You can further refine the declaration of
Library
to useLibrary<E extends Media>
. The compiler will enforce the constraint that aLibrary
can only containMedia
objects (and not, say,Number
s).If you use any of the Java programming libraries that deal with groups of data, such as classes or interfaces that deal with collections, lists, arrays, and vectors, you will notice that they make extensive use of generics.
Note: When compiling code that refers to generics, you might encounter a message like this:This error means that you have bypassed generics and have lost the benefit of compile-time type checking. You should fix your code to make full use of generics and take advantage of compile-time type checking.Note: MyFile.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.As mentioned in the text of the sample error, using the
-Xlink:unchecked
javac
option gives you the most information available about unchecked or type unsafe operations.This covers a simple case of using a generic class. Subsequent sections go into generic types in more detail and touch on generic methods.
Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.