I am using IntelliJ IDEA with javac on JDK 1.8. I have the following code:
class Test<T extends Throwable>
{
@SafeVarargs
final void varargsMethod( Collection<T>... varargs )
{
arrayMethod( varargs );
}
void arrayMethod( Collection<T>[] args )
{
}
}
IntelliJ IDEA does not highlight anything in the above code as a warning. However, when compiling, the following line appears in the "Make" tab of the "Messages" view:
Warning:(L, C) java: Varargs method could cause heap pollution from non-reifiable varargs parameter varargs
Note #1: I have already specified @SafeVarargs
.
Note #2: Warning:(L,C)
points to varargs
being passed as an argument to arrayMethod()
Assuming that I know what I am doing, and supposing that I am pretty sure that there will be no heap pollution or that I promise that I will not call this method in some funky way which might result in heap pollution, what do I need to do to suppress this warning message?
NOTE: There is a multitude of questions on stackoverflow regarding varargs methods, but it appears that there is none that addresses this specific problem. As a matter of fact, the entire interwebz appear to be rather poor in answers to this particular question.
None of the answers I've seen on this question seem to me to be satisfactory so I thought I'd take a stab at it.
Here's the way I see it:
@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
.So if I take the following simple variation on OP's original code:
class Foo {
static <T> void bar(final T... barArgs) {
baz(barArgs);
}
static <T> void baz(final T[] bazArgs) { }
}
The output of $ javac -Xlint:all Foo.java
using the Java 9.0.1 compiler is:
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
I can make that warning go away by tagging bar()
as @SafeVarargs
. This both makes the warning go away and, by adding varargs safety to the method contract, makes sure that anyone who calls bar
will not have to suppress any varargs warnings.
However, it also makes the Java compiler look more carefully at the method code itself - I guess in order to verify the easy cases where bar()
might be violating the contract I just made with @SafeVarargs
. And it sees that bar()
invokes baz()
passing in barArgs
and figures since baz()
takes an Object[]
due to type erasure, baz()
could mess up the heap, thus causing bar()
to do it transitively.
So I need to also add @SuppressWarnings("varargs")
to bar()
to make that warning about bar()
's code go away.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With