类型安全:变量参数子树可能造成堆污染



我正在阅读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,我得到了警告:

类型安全:变量参数子树可能造成堆污染

我如何检查我的代码是否安全?

我如何检查我的代码是否安全?

如果来访者只依赖于subtrees的元素是Tree<E>,而不依赖于subtreesTree<E>[],这是安全的。如果是这种情况,那么您应该用@SafeVarargs注释visit方法。

关于泛型和非可实现类型的Java教程涵盖了您的问题

当参数化类型的变量引用不属于该参数化类型的对象时,就会发生堆污染


当编译器遇到varargs方法时,它将varargs形式形参转换为数组。但是,Java编程语言不允许创建参数化类型的数组。在ArrayBuilder方法中。addToList,编译器翻译变量形式参数T…元素到形式参数T[]元素,一个数组。但是,由于类型擦除,编译器将varargs形式形参转换为Object[]元素。因此,存在堆污染的可能性。

最新更新