类型安全:可变参数子树的潜在堆污染

Type safety: Potential heap pollution via varargs parameter subtrees

我正在阅读 J. Bloch 的有效 Java 并且我知道未经检查的转换永远不会好,除非我们确保转换是安全的。现在,由于 Java 集合框架没有为我们提供 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,我收到警告:

Type safety: Potential heap pollution via varargs parameter subtrees

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

这篇关于泛型和不可具体化类型的 Java Tutorial 涵盖了您的问题

Heap pollution occurs when a variable of a parameterized type refers to an object that is not of that parameterized type


When the compiler encounters a varargs method, it translates the varargs formal parameter into an array. However, the Java programming language does not permit the creation of arrays of parameterized types. In the method ArrayBuilder.addToList, the compiler translates the varargs formal parameter T... elements to the formal parameter T[] elements, an array. However, because of type erasure, the compiler converts the varargs formal parameter to Object[] elements. Consequently, there is a possibility of heap pollution.

How can I check that my code actually safe?

访问者只依赖subtrees的元素是Tree<E>,而不依赖subtreesTree<E>[]的事实是安全的.如果是这种情况,那么您应该使用 @SafeVarargs.

注释 visit 方法