我正在阅读有效的java项目#29,喜欢泛型类型。
我对这个项目在谈到选择解决方案1或解决方案2的原因时提到的堆污染感到困惑。
这两种消除通用数组创建的技术都有其追随者。第一个更具可读性:数组被声明为e[]类型,明确表示它只包含e示例。它也更简洁:在一个典型的泛型类中,您在代码中的多个点读取数组;第一种技术只需要一次转换(创建数组的地方),而第二种技术每次读取数组元素时都需要一次单独的转换。因此,第一种技术更可取,在实践中更常用。但是,它确实会导致堆污染(第32项):数组的运行时类型与其编译时类型不匹配(除非e恰好是对象)。这使得一些程序员非常不安,他们选择了第二种技术,尽管在这种情况下堆污染是无害的。
在我看来,这意味着一些程序员可能会担心解决方案1的“堆污染”,所以他们可能会选择解决方案2。我的理解正确吗?javaMaven能帮我弄清楚为什么堆污染会发生在解决方案1或解决方案2上吗?
没有泛型的原始代码
// Object-based collection - a prime candidate for generics
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
通用解决方案#1
public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = (E[]) new Object[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; // Eliminate obsolete reference
return result;
}
... // no changes in isEmpty or ensureCapacity
}
通用解决方案#2
public class Stack<E> {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size == 0)
throw new EmptyStackException();
E result = (E) elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}
... // no changes in isEmpty or ensureCapacity
}
1条答案
按热度按时间gupuwyp21#
在解决方案2中,您必须在pop方法中使用不推荐的方法。您的代码不是类型安全。如果方法更复杂,可能会产生错误。你没有任何好处,因为它。
另一个类似的例子是get方法。你还必须投: