我有一种 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/