Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过varargs参数可能导致堆污染_Java_Eclipse_Generics_Variadic Functions - Fatal编程技术网

Java 通过varargs参数可能导致堆污染

Java 通过varargs参数可能导致堆污染,java,eclipse,generics,variadic-functions,Java,Eclipse,Generics,Variadic Functions,我理解Java 7在使用泛型类型的varargs时会出现这种情况 但我的问题是 Eclipse说“它的使用可能会污染堆”的确切含义是什么 及 新的@SafeVarargs注释如何防止这种情况发生?@SafeVarargs并不能防止这种情况发生,但它要求编译器在编译使用它的代码时更加严格 更详细地解释了这一点 堆污染是指当您在通用接口上执行操作时得到一个ClassCastException,并且它包含声明之外的另一种类型。堆污染是一个技术术语。它引用的类型不是所指向对象的超类型的引用 List&l

我理解Java 7在使用泛型类型的varargs时会出现这种情况

但我的问题是

Eclipse说“它的使用可能会污染堆”的确切含义是什么


新的
@SafeVarargs
注释如何防止这种情况发生?

@SafeVarargs
并不能防止这种情况发生,但它要求编译器在编译使用它的代码时更加严格

更详细地解释了这一点


堆污染是指当您在通用接口上执行操作时得到一个
ClassCastException
,并且它包含声明之外的另一种类型。

堆污染是一个技术术语。它引用的类型不是所指向对象的超类型的引用

List<A> listOfAs = new ArrayList<>();
List<B> listOfBs = (List<B>)(Object)listOfAs; // points to a list of As

@SafeVarargs
根本无法阻止这一点。然而,有些方法可以证明不会污染堆,编译器无法证明。以前,此类API的调用者会收到恼人的警告,这些警告完全没有意义,但必须在每个调用站点进行抑制。现在API作者可以在声明站点对其进行一次抑制


但是,如果该方法实际上不安全,用户将不再收到警告。

使用varargs时,可能会创建一个
对象[]
来保存参数

由于escape分析,JIT可以优化此阵列创建。(我发现这是为数不多的一次)它不一定会被优化,但我不会担心它,除非你在内存分析器中看到它的问题

AFAIK
@SafeVarargs
禁止编译器发出警告,并且不会更改JIT的行为方式。

当您声明

publicstaticvoidfoo(List…bar)
编译器将其转换为

publicstaticvoidfoo(列表[]条)

publicstaticvoidfoo(列表[]条)

这样一来,您可能会错误地将不正确的值分配到列表中,并且编译器不会触发任何错误。例如,如果
T
字符串
,则以下代码将编译无误,但在运行时将失败:

// First, strip away the array type (arrays allow this kind of upcasting)
Object[] objectArray = bar;

// Next, insert an element with an incorrect type into the array
objectArray[0] = Arrays.asList(new Integer(42));

// Finally, try accessing the original array. A runtime error will occur
// (ClassCastException due to a casting from Integer to String)
T firstElement = bar[0].get(0);
如果您检查了该方法以确保其不包含此类漏洞,则可以使用
@SafeVarargs
对其进行注释以抑制警告。对于接口,请使用
@SuppressWarnings(“未选中”)

如果您收到此错误消息:

Varargs方法可能会由于不可恢复的Varargs参数而导致堆污染

如果您确信您的使用是安全的,那么您应该使用
@SuppressWarnings(“varargs”)
。有关第二种错误的详细解释,请参见和

参考资料: