什么是Java代码造成堆污染的显然正确的例子吗?

user118967:

我试图决定做什么,每次我得到一个Java堆污染警告使用参数时,在可变参数,例如

public static <T> LinkedList<T> list(T... elements) {
    ...
}

在我看来,如果我有信心不使用一些奇怪的强制转换在我的方法,我应该只使用@SafeVarargs,继续前进。但是,这是正确的,或者我需要更加小心?是否有明显正确的代码中使用参数化的可变参数的时候,实际上是不是安全的?

阅读这个话题,我注意到,所提供的例子是相当人为的。例如,Java文档显示以下故障方法:

public static void faultyMethod(List<String>... l) {
    Object[] objectArray = l;     // Valid
    objectArray[0] = Arrays.asList(42);
    String s = l[0].get(0);       // ClassCastException thrown here
}

这是说教,但相当不现实的; 经验丰富的程序员可能不会写代码,做这样的东西。另一个例子

Pair<String, String>[] method(Pair<String, String>... lists) { 
   Object[] objs = lists; 
   objs[0] = new Pair<String, String>("x", "y");  
   objs[1] = new Pair<Long, Long>(0L, 0L);  // corruption !!! 
   return lists; 
} 

这又是非常明显的不切实际的方式混合类型。

那么,还有在堆污染下的参数可变参数发生更微妙的情况下?我在使用合理的@SafeVarargs在失去打字的信息,或者混合类型不正确的方式,如果我不是铸造变量?换句话说,我在治疗这一警告的不是很重要形式是否合理?

user118967:

要声明的通用阵列T[]在Java中,因为它们的类型是在运行时不知道,并因此,它们有可能被滥用,如问题显示的例子是有问题的。因此,只要做到这一点的Java编译器发出警告。

举例来说,如果我们声明一个通用的阵列中

T[] tArray = (T[]) new Object[] { 42 };

我们得到了一个“未投”的警告。

除了这些类型转换,引入一个通用的阵列划分为程序的唯一的其他方式是通过使用一个通用的可变参数。例如,在

void bar() {
    foo(new Integer[]{ 42 })
}

void foo(T... args) {
}

在这里再次通用阵列正在引进,但在比选中投以不同的方式,所以它得到了自己特定的警告,以确保用户不会滥用它。

事实上,只要一个不数组转换为不同类型的数组,似乎使用@SafeVarargs应该是安全的使用,除非非典型类型转换。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章