【问题标题】:Type safety: Potential heap pollution via varargs parameter subtrees [duplicate]类型安全:通过 varargs 参数子树造成的潜在堆污染 [重复]
【发布时间】:2015-09-30 04:27:40
【问题描述】:

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

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

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

【问题讨论】:

    标签: java variadic-functions


    【解决方案1】:

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

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

    【讨论】:

    • 访问方法只是遍历可变参数列表。那安全吗>
    • 我的直觉猜测是只进行迭代是安全的,但如果有知识的人可以确认...?
    • @pallgeuer:是的,只是迭代 varargs 数组是安全的,因为它只依赖于元素的类型(变量参数的类型),而不是数组本身的类型。跨度>
    • 在阅读了您对其他问题的回答后,终于明白了真正的问题是什么:stackoverflow.com/a/38910556/12235376
    【解决方案2】:

    这个Java Tutorial关于泛型和不可实现类型涵盖了你的问题

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


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

    【讨论】:

      猜你喜欢
      • 2012-09-09
      • 2016-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      相关资源
      最近更新 更多