Ответ 1
Например, foo()
небезопасен, он может хранить не-T в массиве, вызывая проблему в [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]
}
Отметив метод с помощью @SafeVarargs, вы обещаете компилятору, что вы не делаете ничего такого непослушного.
Но как, черт возьми, мы можем получить общий массив в [1] для начала? Java не разрешает создание общего массива!
Единственным санкционированным способом создания общего массива является вызов метода vararg
foo( list_int_1, list_int_2 )
тогда массив недоступен для вызывающего абонента, вызывающий не может делать [2] в любом случае, не имеет значения, как foo()
помещается в массив.
Но тогда вы думаете об этом, бэкдор для создания общего массива
@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
return Arrays.copyOf(array, length);
}
List<String>[] array1 = newArray(10);
и общий литерал массива
@SafeVarargs
static <E> E[] array(E... array)
{
return array;
}
List<String>[] array2 = array( list1, list2 );
Итак, мы можем создать общий массив в конце концов... Глупый Java, пытаясь помешать нам это сделать.