我知道Java 7在使用泛型类型的varargs时会出现这种情况;
但我的问题是..
当Eclipse说“它的使用可能会潜在地污染堆”时,它到底是什么意思?
而且
新的@safevarargs
注释如何防止这种情况发生?
当你申报时
public static
编译器将其转换为
public static
然后到
公共静态无效文件(list[]bar)
这样就会出现这样的危险:您会错误地将不正确的值分配到列表中,而编译器将不会触发任何错误。例如,如果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(“unchecked”)
。
如果收到以下错误消息:
Varargs方法可能会导致堆污染,因为Varargs参数不可重构
并且您确信您的使用是安全的,那么您应该改用@suppresswarnings(“varargs”)
。请参见@safeVarargs是此方法的适当注释吗?和https://stackoverflow.com/a/14252221/14731来解释第二种错误。
参考资料:
堆污染是一个专业术语。它引用具有不是它们所指向对象的超类型的类型的引用。
List<A> listOfAs = new ArrayList<>();
List<B> listOfBs = (List<B>)(Object)listOfAs; // points to a list of As
这可能导致“无法解释的”ClassCastException
。
// if the heap never gets polluted, this should never throw a CCE
B b = listOfBs.get(0);
@safevarargs
完全不阻止这一点。然而,有一些方法可以证明不会污染堆,编译器就是无法证明。以前,这类API的调用者会得到恼人的警告,这些警告完全没有意义,但必须在每个调用站点上加以抑制。现在API作者可以在声明站点将其抑制一次。
但是,如果该方法实际上并不安全,用户将不再受到警告。
问题内容: 我知道在Java 7中使用带有泛型类型的varargs时会发生这种情况。 但是我的问题是.. Eclipse说“使用它可能会污染堆”时,这到底是什么意思? 和 新注释如何防止这种情况? 问题答案: 堆污染是一个技术术语。它引用的引用类型不是其指向的对象的超类型。 这可能会导致“无法解释” 。 @SafeVarargs完全不能阻止这一点。但是,有些方法证明不会污染堆,编译器无法证明这一点
此问题特定于将varargs与泛型一起使用: 为什么我会得到这个警告如果我像下面这样定义方法: 与此相反的是: 因此,在声明方法之前,我应该注意什么? 此问题类似于以下关于,但这些答案中显示的方案似乎不适用于: null null 这就是我试图污染堆的原因,但是每次错误的尝试都会导致而不是污染数组。 我使用的是Eclipse4.6.0和Java JDK8U74。
问题内容: 我在JDK 1.8上将IntelliJ IDEA与javac一起使用。我有以下代码: IntelliJ IDEA不会在上面的代码中突出显示任何内容作为警告。但是,在编译时,以下行将显示在“消息”视图的“生成”选项卡中: 警告:(L,C)java:Varargs方法可能会导致不可修改的varargs参数varargs造成堆污染 注意#1:我已经指定了。 注意#2:指向作为参数传递给 假设
描述 HTTP 参数污染,或者 HPP,在网站接受用户输入,将其用于生成发往其它系统的 HTTP 请求,并且不校验用户输出的时候发生。它以两种方式产生,通过服务器(后端)或者通过客户端。 在 StackExchange 上,SilverlightFox 提供了一个 HPP 服务端攻击的不错的例子。假设我们拥有以下站点:https://www.example.com/transferMoney.ph
但是,如果Terminal中没有提供,我不知道如何(或者是否能够)为其设置默认值。像这样简单的东西不起作用。这里的一个解决方案是根据的内容或大小在函数中设置变量。但我不知道有没有更好的办法做到这一点。 因此,我正在寻找一种方法来使用来自终端的参数调用一个函数,其中需要一个数字(在本例中为2),而其余的是可选的,并设置为默认值。
问题内容: 考虑方法声明: 该Object …参数只是对Objects 数组的引用。有没有办法在引用实际Object数组时使用此方法?如果我将Object数组传递给…参数-结果参数值将是一个二维数组-因为an Object[]本身就是an Object: 因此,数组的第一个组件(String.format方法中使用了哪个)将是一个数组,他将生成: 然后由于数组大小为1而发生错误。 该大胆的顺序是真