我正在阅读J. Bloch的有效Java,除非我们确保演员是安全的,否则我认为未经检查的演员阵容永远不会好。现在,由于Java Collection框架没有为我们提供Tree
数据结构,我必须自己编写。
public interface TreeVisitor<E, R> {
public R visit(E leaf);
public R visit(E val, Tree<E>... subtrees);
}
public abstract class Tree<E> {
public abstract <R> R accept(TreeVisitor<E, R> visitor);
public Tree<E> leaf(E leaf) {
return new Tree<E>() {
@Override
public <R> R accept(TreeVisitor<E, R> visitor) {
return visitor.visit(leaf);
}
};
}
public Tree<E> branch(E value, Tree<E>... subtrees){ //1
return new Tree<E>(){
@Override
public <R> R accept(TreeVisitor<E, R> visitor) {
return visitor.visit(value, subtrees);
}
};
}
}
在//1
,我收到了警告:
类型安全:通过varargs参数子树潜在的堆污染
如何检查我的代码是否真的安全?
答案 0 :(得分:1)
这个关于泛型和不可再生类型的Java Tutorial涵盖了您的问题
当参数化类型的变量引用不属于该参数化类型的对象时,会发生堆污染
当编译器遇到varargs方法时,它会将varargs形式参数转换为数组。但是,Java编程语言不允许创建参数化类型的数组。在方法ArrayBuilder.addToList中,编译器将varargs形式参数T ...元素转换为形式参数T []元素,即数组。但是,由于类型擦除,编译器会将varargs形式参数转换为Object []元素。因此,存在堆污染的可能性。
答案 1 :(得分:1)
如何检查我的代码是否真的安全?
如果访问者仅依赖于subtrees
的元素Tree<E>
这一事实,并且不依赖subtrees
为Tree<E>[]
这一事实,那么这是安全的。如果是这种情况,那么您应该使用visit
注释@SafeVarargs
方法。