觀察下面的代碼:
public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new E[DEFAULT_INITIAL_CAPACITY];
}
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size == 0)
throw new EmptyStackException();
E result = elements[--size];
elements[size] = null;
return result;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
上面是一個轉化stack類到stack<E>的代碼。由於不能創建不可具體化類型的數組,所以new E[DEFAULT)INITIAL_CAP]是不允許的。
解決辦法有兩種:
(1)創建一個Object數組,並將它轉換成泛型數組類型:
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
錯誤變成警告,因爲我們可以保證類型安全,所以可以用SupressWarning註釋忽略掉該警告。
(2)將elements域的類型從E[]改爲Object[]
private Object[] elements;
E result = (E) elements[--size];
與第一種情況類似。這也會得到一條警告,同樣的,也可證明這種情況下是安全的,所以可以禁止該警告。依據最小化原則,應該直接在此名上加註釋來禁止警告。實際應用中由於需要頻繁調用pop()方法,由於(2)方法需要頻繁轉化,(1)是更推薦的,但(1)由於是轉化數組類型顯然是沒有(2)轉化標量類型更安全的。所以選取哪種方法就看個人抉擇了。