Sunday 20 September 2009

Item 26: Favor generic types

Continuing the series on generics, this item gives advice on writing your own generic types. As an example, we are guided through the process of generifying a Stack class. Along the way, we come across a couple of obstacles, and this item suggests solutions to these.

The original Stack had the following constructor:

public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}

When developing the generic version Stack<E> we may think we can write
this constructor:

public Stack() {
elements = new E[DEFAULT_INITIAL_CAPACITY];
}

Unfortunately, this fails to compile because the new operator can't deal with arrays of generic types. So instead we can create an array of Object and cast it to the generic type:

elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];

Instead of an error, we get an "unchecked cast" warning. This normally indicates that what we are doing is not type-safe. But in our class, the array that we create is private, so we know every use of it, and can figure out that what we are doing is safe. We can therefore use a @SuppressWarnings("unchecked") annotation.

Alternatively, we can keep 'elements' as an Object[] array, and then cast every reference of 'elements' where a generic type is required:

E result = (E) elements[--size];

This again emits an unchecked cast warning, which we can also suppress.

Klitos Kyriacou

No comments: