Declaring and Using Your Own Generic Types

It is not difficult to declare your own generic types. In addition to specifying a formal type parameter list, your generic type specifies its type parameter(s) throughout its implementation. For example, Listing 5-24 declares a Oueue<E> generic type.

Listing 5-24. Declaring and using a Oueue<E> generic type public class Oueue<E>

private E[] elements; private int head, tail; @SuppressWarnings("unchecked") public Oueue(int size)

elements = (E[]) new Object[size]; head = 0; tail = 0;

public void insert(E element) {

if (isFull()) // insert() should throw an exception when full. I did return; // not implement insert() to do so for brevity. elements[tail] = element; tail = (tail+1)%elements.length;

if (isEmpty()) return null; E element = elements[head]; head = (head+1)%elements.length; return element;

public boolean isEmpty() {

return head == tail;

public boolean isFull() {

return (tail+1)%elements.length == head;

public static void main(String[] args) {

Oueue<String> queue = new 0ueue<String>(5);

System.out.println(queue.isEmpty());

queue.insert("A");

queue.insert("B");

queue.insert("C");

queue.insert("D");

queue.insert("E");

System.out.println(queue.isFull());

System.out.println(queue.remove());

queue.insert("F");

while (!queue.isEmpty())

System.out.println(queue.remove()); System.out.println(queue.isEmpty()); System.out.println(queue.isFull());

Queue implements a queue, a data structure that stores elements in first-in, first-out order. An element is inserted at the tail and removed at the head. The queue is empty when the head equals the tail, and full when the tail is one less than the head.

Notice that Queue<E>'s E type parameter appears throughout the source code. For example, E appears in the elements array declaration to denote the array's element type. E is also specified as the type of insert()'s parameter and as remove()'s return type.

E also appears in elements = (E[]) new Object[size];. (I will explain later why I specified this expression instead of specifying the more compact elements = new E[size]; expression.)

The E[] cast results in the compiler warning about this cast being unchecked. The compiler is concerned that downcasting from Object[] to E[] might result in a violation of type safety because any kind of object can be stored in Object[].

The compiler's concern is not justified in this example. There is no way that a non-E object can appear in the E[] array. Because the warning is meaningless in this context, it is suppressed by prefixing the constructor with @SuppressWarnings("unchecked").

CAUTION: Be careful when suppressing an unchecked warning. You must first prove that a ClassCastException cannot occur, and then you can suppress the warning.

When you run this application, it generates the following output:

true true

true false

Was this article helpful?

0 0

Post a comment