我在 JDK 1.8 上使用 IntelliJ IDEA 和 javac。我有以下代码:
class Test<T extends Throwable>
{
@SafeVarargs
final void varargsMethod( Collection<T>... varargs )
{
arrayMethod( varargs );
}
void arrayMethod( Collection<T>[] args )
{
}
}
IntelliJ IDEA 不会高亮上述代码中的任何内容作为警告。但是,在编译时,“消息” View 的“制作”选项卡中会出现以下行:
Warning:(L, C) java: Varargs method could cause heap pollution from non-reifiable varargs parameter varargs
注意#1:我已经指定了@SafeVarargs。
注意 #2:Warning:(L,C) 指向 varargs 作为参数传递给 arrayMethod()
假设我知道我在做什么,并且假设我非常确定不会有堆污染,或者我保证我不会以某种可能导致堆污染的时髦方式调用此方法,我需要做什么才能禁止显示此警告消息?
注意:stackoverflow 上有很多关于可变参数方法的问题,但似乎没有一个可以解决这个特定问题。事实上,整个 interwebz 似乎都无法很好地回答这个特定问题。
最佳答案
在我看来,关于这个问题的答案都不是令人满意的,所以我想尝试一下。
这是我的看法:
@SafeVarargs [unchecked] Possible heap pollution from parameterized vararg type Foo .@SuppressWarnings("varargs") [varargs] Varargs method could cause heap pollution from non-reifiable varargs parameter bar .因此,如果我对 OP 的原始代码进行以下简单修改:
class Foo {
static <T> void bar(final T... barArgs) {
baz(barArgs);
}
static <T> void baz(final T[] bazArgs) { }
}
$ javac -Xlint:all Foo.java 的输出使用 Java 9.0.1 编译器是:
Foo.java:2: warning: [unchecked] Possible heap pollution from parameterized vararg type T
static <T> void bar(final T... barArgs) {
^
where T is a type-variable:
T extends Object declared in method <T>bar(T...)
1 warning
我可以通过标记 bar() 使警告消失作为@SafeVarargs .这既使警告消失又,通过向方法契约添加可变参数安全性,确保任何调用bar的人。不必抑制任何可变参数警告。
然而,它也让 Java 编译器更仔细地查看方法代码本身——我想是为了验证 bar() 的简单情况。可能违反了我刚刚与 @SafeVarargs 签订的契约(Contract).它看到 bar()调用 baz()路过barArgs自baz()以来的数字需要 Object[]由于类型删除,baz()可能会弄乱堆,从而导致 bar()以传递方式进行。
所以我还需要添加 @SuppressWarnings("varargs")至 bar()发出关于 bar() 的警告的代码消失了。
关于Java 警告 : Varargs method could cause heap pollution from non-reifiable varargs parameter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28914088/