Here is the code:
class Foo<T> {
private final T[] array;
@SafeVarargs
Foo(T... items) {
this.array = items;
}
}
I'm getting:
[WARNING] Varargs method could cause heap pollution
from non-reifiable varargs parameter items
What's wrong with my assignment? How to fix that? @SuppressWarnings
is not an option, since I want this constructor to be truly "safe."
$ javac -version
javac 1.8.0_40
From the docs:
Applying this annotation to a method or constructor suppresses unchecked warnings about a non-reifiable variable arity (vararg) type and suppresses unchecked warnings about parameterized array creation at call sites.
The first statement tells us @SafeVarargs
suppresses unchecked warnings about:
In your case, @SafeVarargs
is suppressing the warning on T... items
. Your warning is occuring on this.array = items;
.
From the JLS §9.6.4.7:
The annotation
@SafeVarargs
has non-local effects because it suppresses unchecked warnings at method invocation expressions in addition to an unchecked warning pertaining to the declaration of the variable arity method itself.
In contrast, the annotation
@SuppressWarnings("unchecked")
has local effects because it only suppresses unchecked warnings pertaining to the declaration of a method.
Joshua Bloch explains this in Effective Java (25s chapter):
The prohibition on generic array creation can be annoying. It means, for example, that it’s not generally possible for a generic type to return an array of its element type (but see Item 29 for a partial solution). It also means that you can get confusing warnings when using varargs methods (Item 42) in combination with generic types. This is because every time you invoke a varargs method, an array is created to hold the varargs parameters. If the element type of this array is not reifiable, you get a warning. There is little you can do about these warnings other than to suppress them (Item 24), and to avoid mixing generics and varargs in your APIs.
The reason for this message is described in spec, in this part of spec, there is similar example (with class ArrayBuilder and different combinations of annotation usage)
Like alternative, try to use mix of SafeVarargs and SuppressWarnings annotations
@SafeVarargs
@SuppressWarnings( "varargs" )
HTH
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