The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Trail: Learning the Java Language
Lesson: Classes and Inheritance

Defining and Using Generic Types

To define a generic, you include type parameters following the type name. The type parameters are a comma separated list of identifiers delimited by angle brackets. By convention, type parameters are uppercase letters. The type parameters then appear in the type's methods, either as the type of arguments in the method's parameter list or as the type of its return value. In practice most developers won't need to define new generics, but you should recognize the syntax and learn how to use generics.

Let's revisit the Stack class introduced in section Creating Classes (in the Learning the Java Language trail). The generic version, Stack2<T>, uses a generic collection, ArrayList<T>, to contain the items in the stack:

public class Stack2<T> {
    private ArrayList<T> items;
    ...
    public void push(T item) {}
    public T pop() {}
    public boolean isEmpty() {}
}
Notice how the type parameter T is introduced after the class name and then appears as the argument type of the push method and the return type of the pop method.

Collections (in the Learning the Java Language trail) are often used to demonstrate how to use generic types because they feature heavily in the collection interfaces and classes. In fact, collections were a major motivation behind the introduction of generics to the Java language because they enable compile-time checking of the type safety of operations on the collection. When you specify the type of object stored in a collection:

As stated earlier, when you use a generic, you substitute an actual type argument for the parameter, much the same way you substitute actual values for method parameters. The actual type argument must be a reference type; it cannot be a primitive. For example, here is how would you instantiate Stack2 with the type argument String, and then push and pop the String "hi":
Stack2<String> s = new Stack2<String>();
s.push("hi");
String greeting = s.pop(); //no cast required here
With a non-generic stack this code would be:
Stack2 s = new Stack2();
s.push("hi");
String greeting = (String)s.pop(); //cast required here
Note when a generic is instantiated, the compiler translates generics by a technique called type erasure. Basically, the compiler removes all information related to type parameters and type arguments. For instance, Stack2<String> is translated to type Stack2, which is called the raw type. The implication of type erasure is that the type argument is not available at runtime for use in casts or as the argument to the instanceof method.

Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.