Упрощенный вызов метода Varargs в Java 7

В Java 7 у вас есть возможность помещать аннотацию @SafeVarargs для подавления предупреждения, которое вы получаете при компиляции метода с невосстанавливаемым параметром varargs. Проект Coin предусматривает, что аннотация должна использоваться, когда метод гарантирует, что в массив varargs хранятся только элементы того же типа, что и параметр varargs.

Что будет примером небезопасного метода?

Ответы

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