Например, 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, пытаясь помешать нам сделать это.