18

In Java 7, you have the option to put a @SafeVarargs annotation to suppress the warning you get when compiling a method with a non-reifiable varargs parameter. Project Coin's proposal stipulates that the annotation should be used when the method ensures that only elements of the same type as the varargs parameter are stored in the varargs array.

What would be an example of a non-safe method?

palacsint
  • 28,416
  • 10
  • 82
  • 109
Jeffrey
  • 44,417
  • 8
  • 90
  • 141

1 Answers1

25

For example, foo() is not safe, it may store non-T in the array, causing problem at [2]

<T extends List<?>> void foo(T... args)
{
    List<String>[] array2 = (List<String>[])args;
    array2[0] = a_list_of_string;
}

void test2()
{
    List<Integer>[] args = ...;   // [1]
    foo(args);
    Integer i = args[0].get(0);   // [2]
}

By marking the method with @SafeVarargs, you promise to compiler that you are not doing anything naughty like that.


But how in hell can we get a generic array at [1] to start with? Java doesn't allow generic array creation!

The only sanctioned way of generic array creation is when calling a vararg method

foo( list_int_1, list_int_2 )

then the array isn't accessible to caller, caller can't do [2] anyway, it doesn't matter how foo() messes with the array.

But then you think about it, it is the backdoor to create generic array

@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
    return Arrays.copyOf(array, length);
}

List<String>[] array1 = newArray(10);

and generic array literal

@SafeVarargs
static <E> E[] array(E... array)
{
    return array;
}

List<String>[] array2 = array( list1, list2 );

So we can create generic array after all... Silly Java, trying to prevent us from doing that.

irreputable
  • 44,725
  • 9
  • 65
  • 93
  • 1
    You can create generic arrays without varargs methods, but you have to use [Array#newInstance(Class> type, int length)](http://tinyurl.com/3uzbb7v) and cast it. Thanks for the thorough answer. – Jeffrey Oct 22 '11 at 15:42
  • Not really a "simplification", but an improved hint. – Flueras Bogdan Dec 06 '12 at 12:37
  • Im trying this example and I see no change in behavior with and without using @SafeVarargs. I still get a warning "Type Safety: A generic array of List...." – excalibur Mar 02 '15 at 17:42