观察下面的代码:
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)转化标量类型更安全的。所以选取哪种方法就看个人抉择了。