Let us revise the stack class in §9.10, "A Custom Stack Class," to generalize the element type with a generic type. The new stack class, named GenericStack , is shown in Figure 21.4 and is implemented in Listing 21.1.
1 public class GenericStack <E> { 2 public final static int INITIAL_SIZE = 16 ; 3 private E[] elements; 4 private int size ; 5 6 /** Construct a stack with the default initial capacity */ 7 public GenericStack() { 8 this (INITIAL_SIZE); 9 } 10 11 /** Construct a stack with the specified initial capacity */ 12 public GenericStack( int initialCapacity) { 13 elements = ( E[] ) new Object[initialCapacity]; 14 } 15 16 /** Push a new element into the top of the stack */ 17 public E push( E value) { 18 if (size >= elements.length) { 19 E [] temp = ( E[] ) new Object[elements.length * 2 ]; 20 System.arraycopy(elements, , temp, , elements.length); 21 elements = temp; 22 } 23 24 return elements[size++] = value; 25 } 26 27 /** Return and remove the top element from the stack */ 28 public E pop() { 29 return elements[--size]; 30 } 31 32 /** Return the top element from the stack */ 33 public E peek() { 34 return elements[size - 1 ]; 35 } 36 37 /** Test whether the stack is empty */ 38 public boolean isEmpty() { 39 return size == ; 40 } 41 42 /** Return the number of elements in the stack */ 43 public int getSize() { 44 return size; 45 } 46 } |
Here is an example that creates a stack to hold strings and adds three strings to the stack:
GenericStack <String> stack1 = new GenericStack <String> (); stack1.push( "London" ); stack1.push( "Paris" ); stack1.push( "Berlin" );
Here is another example that creates a stack to hold integers and adds three integers to the stack:
GenericStack <Integer> stack2 = new GenericStack <Integer> (); stack2.push( 1 ); // auto boxing 1 to new Integer(1) stack2.push( 2 ); stack2.push( 3 );
Note
Instead of using a generic type in Listing 21.1, you could simply make the type element Object , which can accommodate any object type. However, using generic types can improve software reliability and readability because certain errors can be detected at compile time rather than at runtime. For example, since stack1 is declared GenericStack<String> , only strings can be added to the stack. It would be a compilation error if you attempted to add an integer to stack1 . |
You cannot create an instance using a generic type parameter. For example, the expression new E() or new E[10] would be wrong. To circumvent this limitation, an array of the Object type is created in line 12, and cast into E[] . You need to compile the program with the option “Xlint:unchecked ,
javac “Xlint:unchecked GenericStack.java
The compiler, however, issues a warning about this casting:
GenericStack.java:12: warning: [unchecked] unchecked cast found : java.lang.Object[] required: E[] elements = ( E[] )new Object[capacity];
The reason for this warning is that the compiler cannot ensure that casting will always succeed. For example, if E is String and new Object[] is an array of Integer objects, (String[])(new Object[]) would cause a ClassCastException . Note that ClassCastException will never occur in this case, because every object pushed to the stack must be an instance of the generic type E .
Caution
To create a stack of strings, you use new GenericStack<String>() . This could mislead you into thinking that the constructor of GenericStack should be declared as public GenericStack<E>() This is wrong. It should be declared public GenericStack() |
Caution
You cannot substitute a generic type with a primitive type such as int , double , char , etc., because a generic type must be a reference type. However, you can use wrapper classes such as Integer , Double , Character , etc, instead. |
Caution
A generic class cannot be a subclass of java.lang.Throwable , so the following class declaration would be illegal: public class MyException<T> extends Exception { } |
Note
Occasionally, a generic class may have more than one parameter. In this case, place the parameters together inside the brackets, separated by commas, such as <E1, E2, E3> . |