null

Java и SafeVarargs

В Java часто используются методы, которые могут принимать переменное число аргументов (varargs).

В некоторых случаях при компиляции метода с varargs может быть выдано предупреждение. Например, при попытке скомпилировать следующий фрагмент кода:

static <T> void methodVarArgs(T... els) {
    // implementation
}

Будет выведено предупреждение:

Note: TestCode.java uses unchecked or unsafe operations.

Компилятор выводит предупреждение из-за возможных последствий при использовании varargs. 
Аргументы, переданные в такой параметр, будут представлены массивом, что в комбинации с использованием генериков может привести к ошибкам во время выполнения программы.
Например, при выполнении следующего фрагмента кода:

public class TestCode {
    static <T> void methodVarArgs(T... els) {
        Object[] objs = els;
        String[] strs = {"test"};
        objs[0] = strs;
    }
    
    public static void main(String[] args) {
        methodVarArgs(1, 2, 3);
    }
}

будет ошибка времени выполнения: 

Exception in thread "main" java.lang.ArrayStoreException: [Ljava.lang.String;

Если вы уверены, что метод с varargs безопасен, можно избежать генерации предупреждения во время компиляции программы. 
Для этого нужно использовать аннотацию @SafeVarargs: 

@SafeVarargs
static <T> void methodVarArgs(T... els) {
    for (T t: els) {
        System.out.println(t);
    }
}

Начиная с Java 7, данную аннотацию можно применять к конструкторам и методам.
Стоит отметить, что существует ряд дополнительных ограничений при использовании аннотации SafeVarargs. 
Если в методе/конструкторе не используется varargs или метод не является static или final, то код не получится скомпилировать.

В Java 9 возможности использования аннотации SafeVarargs были расширены, теперь аннотацию SafeVarargs можно применить к private методам, принимающим varargs.