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.