我在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不会在上面的代码中突出显示任何内容作为警告。但是,在编译时,以下行将显示在“消息”视图的“生成”选项卡中:
警告:(L,C)java:Varargs方法可能会导致不可修改的varargs参数varargs造成堆污染
注意#1:我已经指定了@SafeVarargs。
@SafeVarargs
注意#2:Warning:(L,C)指向varargs作为参数传递给arrayMethod()
Warning:(L,C)
varargs
arrayMethod()
假设我知道自己在做什么,并且假设我非常确定不会出现堆污染,或者我保证不会以某种时髦的方式调用此方法,这可能会导致堆污染, 那么我需要做些什么?禁止显示此警告消息?
注意: 关于varargs方法,有很多关于问题,但是似乎没有一个问题可以解决此特定问题。实际上,整个interwebz在回答这个特定问题方面似乎很差。
在这个问题上,我所看到的答案都没有一个令人满意,因此,我认为自己会对此持怀疑态度。
这是我的看法:
[unchecked] Possible heap pollution from parameterized vararg type Foo
@SuppressWarnings("varargs")
是解决警告的方法:[varargs] Varargs method could cause heap pollution from non-reifiable varargs parameter bar。
[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编译器的输出为:
$ javac -Xlint:all Foo.java
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将不必抑制任何可变参数的警告。
bar()
bar
但是,这也使Java编译器更加仔细地查看了方法代码本身- 我想是为了验证一些简单的情况,在这些情况下bar()可能违反了我刚刚订立的合同@SafeVarargs。而且它看到bar()所调用baz()传递barArgs和数据,因为baz()需要一个Object[]因类型擦除,baz()会搞乱了堆,从而导致bar()以传递地做到这一点。
baz()
barArgs
Object[]
因此,我还需要添加@SuppressWarnings("varargs"),bar()以使有关bar()的代码的警告消失。