什么是导致堆污染的Java代码的一个明显正确的例子? [英] What is an apparently correct example of Java code causing heap pollution?

查看:160
本文介绍了什么是导致堆污染的Java代码的一个明显正确的例子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试决定在每次使用参数化的varargs时遇到Java堆污染警告时要做什么,例如

I'm trying to decide what to do every time I get a Java heap pollution warning when using parameterized varargs such as in

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

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

It seems to me that if I am confident not to be using some weird casts in my methods, I should just use @SafeVarargs and move on. But is this correct, or do I need to be more careful? Is there apparently correct code that is actually not safe when using parameterized varargs?

阅读有关主题的内容,我注意到提供的示例非常人为。例如, Java文档显示以下错误方法:

Reading about the subject, I notice that the provided examples are quite artificial. For example, the Java documentation shows the following faulty method:

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
}

这是教学但非常不切实际的;有经验的程序员不太可能编写代码来做这样的事情。另一个示例

which is didactic but pretty unrealistic; experienced programmers are not likely to write code doing stuff like this. Another example is

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; 
} 

这显然是以不切实际的方式混合类型。

which is again pretty obviously mixing types in an unrealistic way.

那么,在参数化的变量下,堆污染是否会发生更微妙的情况?我是否有理由使用 @SafeVarargs 如果我没有以丢失输入信息的方式转换变量,或者错误地混合类型?换句话说,我是否有理由将此警告视为一种不太重要的形式?

So, are there more subtle cases in which heap pollution happens under parameterized varargs? Am I justified in using @SafeVarargs if I am not casting variables in a way that loses typing information, or mixes types incorrectly? In other words, am I justified in treating this warning as a not very important formality?

推荐答案

声明通用数组<$ c Java中的$ c> T [] 是有问题的,因为它们的类型在运行时是未知的,因此它们可能被误用,正如问题中的示例所示。因此,只要这样做,Java编译器就会发出警告。

To declare generic arrays T[] in Java is problematic because their type is not known at run time and as a consequence they can be misused, as the examples in the question show. So the Java compiler issues warnings whenever this is done.

例如,如果我们在

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

我们收到未经检查的演员警告。

we get an "unchecked cast" warning.

此外,这样的强制转换,将通用数组引入程序的唯一方法是使用通用的变量。例如,在

Besides, such casts, the only other way of introducing a generic array into a program is by using a generic varargs. For example, in

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

void foo(T... args) {
}

此处引入了一个通用数组,但其方式与未经检查的强制转换不同,因此它会获得自己的特定警告,以确保用户不会滥用它。

Again here a generic array is being introduced, but in a different way than an unchecked cast, so it gets its own specific warning to make sure the user is not misusing it.

的确,只要一个人没有将数组转换为不同类型的数组,似乎使用 @SafeVarargs 应该是安全的,禁止使用非典型类型转换。

Indeed, as long as one is not converting the array to an array of a different type, it seems that using @SafeVarargs should be safe to use, barring atypical type conversions.

这篇关于什么是导致堆污染的Java代码的一个明显正确的例子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆