什么是导致堆污染的Java代码的一个明显正确的例子? [英] What is an apparently correct example of Java code causing heap pollution?
问题描述
我正在尝试决定在每次使用参数化的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屋!