Is this use of varargs safe?

I have a sort of util method to transform a varargs of a type into an array of that type - it looks like this:

public K[] array(K... ks) {
    return ks;
}

The use case is so that instead of defining an array when calling a method which requires an array, you can simply do array(val1, val2, val3).

However, IntelliJ gives me heap pollution warnings. I understand what this means to an extent, but I don't have much experience with the specifics - so, I would like to know whether I can add @SafeVarargs and whether this method is actually safe.

IntelliJ says:

  Problem synopsis      Possible heap pollution from parameterized vararg type at line 249

Problem resolution    Make final and annotate as @SafeVarargs

K is declared as the type parameter of a class, along with V.

Jon Skeet
people
quotationmark

No, it's not safe - if called from another method which is using generics. Here's a complete example which looks okay, but throws an exception:

class Utility<K> {   
    public K[] array(K... ks) {
        return ks;
    }

    public K[] otherMethod(K k1, K k2) {
        return array(k1, k2);
    }
}    

class Test {
    public static void main(String[] args) throws Exception {
        Utility<String> util = new Utility<String>();
        // Bang!
        String[] array = util.otherMethod("foo", "bar");
    }
}

When the compiler creates the bytecode for otherMethod, it can't create an array of the right kind to pass into array, because it doesn't know the type of K. Due to type erasure, it just creates an Object[] with the values. So in main, there's a hidden cast from the result of otherMethod to String[]... and that fails at execution time.

If you call array directly from code which really knows the types of the arguments, then it's fine, because the implicitly-created array will be of the right type.

people

See more on this question at Stackoverflow