java - 使用可变参数安全吗?

标签 java

我有一种 util 方法可以将一个类型的 varargs 转换为该类型的数组 - 它看起来像这样:

public K[] array(K... ks) {
    return ks;
}

用例是这样的,当调用需要数组的方法时,您可以简单地执行 array(val1, val2, val3),而不是定义数组。

但是,IntelliJ 给了我堆污染警告。我在一定程度上理解这意味着什么,但我对具体细节没有太多经验 - 所以,我想知道我是否可以添加 @SafeVarargs 以及这种方法是否真的安全。

IntelliJ 说:

  Problem synopsis      Possible heap pollution from parameterized vararg type at line 249

Problem resolution    Make final and annotate as @SafeVarargs

K 与 V 一起被声明为类的类型参数。

最佳答案

不,这不安全 - 如果从另一个使用泛型的方法调用。这是一个完整的示例,看起来没问题,但会引发异常:

class Utility<K> {   
    public K[] array(K... ks) {
        return ks;
    }

    public K[] otherMethod(K k1, K k2) {
        return array(k1, k2);
    }
}    

class Test {
    public static void main(String[] args) throws Exception {
        Utility<String> util = new Utility<String>();
        // Bang!
        String[] array = util.otherMethod("foo", "bar");
    }
}

当编译器为 otherMethod 创建字节码时,它不能创建一个正确类型的数组来传递给 array,因为它不知道 K 的类型。由于类型删除,它只创建一个带有值的 Object[]。所以在 main 中,有一个从 otherMethod 的结果到 String[]... 的隐藏转换...并且在执行时失败。

如果您直接从 真正 知道参数类型的代码中调用 array,那很好,因为隐式创建的数组将是正确的类型。

关于java - 使用可变参数安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25584386/

相关文章:

java - 如何在控制台上抑制 hadoop 生成的日志消息

java - 在 Java 中是否可以将 BufferedImage 转换为 IMG 数据 URI?

java - 方法何时更改参数的变量/参数的值?

java - 使用圆圈制作屏幕保护程序。我如何为圆圈创建一个循环以便创建新的圆圈?

java - 读取输入文件到链表的节点错误

Wicket 口中的javascript注入(inject)

java - 无法访问的代码+如何遍历所有组合

java - GAE 中的列表访问同步

java - ChannelHandlerContext setAttachment 方法

java - 表示具有未知节点数的图?