类型安全:通过varargs参数子树的潜在堆污染

我正在阅读J. Bloch的有效Java,除非我们确保演员阵容是安全的,否则我认为未经检查的演员阵容永远不会好。 现在,由于Java Collection框架没有为我们提供Tree数据结构,我必须自己编写。

 public interface TreeVisitor { public R visit(E leaf); public R visit(E val, Tree... subtrees); } public abstract class Tree { public abstract  R accept(TreeVisitor visitor); public Tree leaf(E leaf) { return new Tree() { @Override public  R accept(TreeVisitor visitor) { return visitor.visit(leaf); } }; } public Tree branch(E value, Tree... subtrees){ //1 return new Tree(){ @Override public  R accept(TreeVisitor visitor) { return visitor.visit(value, subtrees); } }; } } 

//1 ,我得到了警告:

类型安全:通过varargs参数子树的潜在堆污染

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

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

如果访问者仅依赖于subtrees Tree的元素是Tree这一事实,并且不依赖于subtreesTree[]的事实,则是安全的。 如果是这种情况,那么您应该使用@SafeVarargs注释visit方法。

这个关于generics和不可再生类型的Java教程涵盖了您的问题

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


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