@SafeVarargs в методе vararg с универсальным возвращаемым типом

Мой метод query, приведенный ниже, упрощает запросы к моему слою сохраняемости, используя org.hibernate.Session. Вот код метода:

public class Persister{

    public static <E> List<E> query(Class<E> c, E... exampleEntities){
        try(Session session = openSession()){
            final Criteria criteria = session.createCriteria(c);
            for(E e : exampleEntities){
                final Example example = Example.create(e);
                criteria.add(example);
            }

            @SuppressWarnings("unchecked")
            final List<E> list = criteria.list();
            /*
             * Empty loop technique ensures all elements in list are of type E
             * otherwise a ClassCastException is thrown. Inspired by
             * "Java Generics" section 8.2
             */
            for(E e : list);
            return list;
        }
    }

    //other methods ommitted
}

Он вызывает следующее предупреждение:

Безопасность типов: потенциальное загрязнение кучи через параметр varargs exampleEntities

Безопасно ли использовать аннотацию @SafeVarargs в этом случае?

Насколько я понимаю, пока я не инициализирую локальный Object[] с exampleEntities, то все в порядке. Но это не кажется правильным.

Этот метод похож на метод java.util.Collections.addAll упоминается в Спецификация Java §9.6.3.7, которая снабжена аннотацией @SafeVarargs. В этом ответе обсуждается предупреждение о том, что в целом следующий код безопасен:

@SafeVarargs
void foo(T... args) {
    for (T x : args) {
        // do stuff with x
    }
}

Но мой метод query имеет вид:

<T> List<T> query(T... args) {
    Foo foo = new Foo();
    for (T x : args) {
        foo.add(x);
    }
    return (List<T>) foo.list();
}

Итак, есть ли случай, когда аннотация @SafeVarargs небезопасна?


person Austin D    schedule 09.03.2016    source источник


Ответы (1)


Да, вы можете использовать @SafeVarargs. Можно ли использовать @SafeVarargs, зависит от того, как вы используете параметр varargs exampleEntities. Если вы полагаетесь на то, что его фактический тип времени выполнения является E[], то вы не можете использовать @SafeVarargs, но если вы полагаетесь только на типы его элементов E, вы можете использовать @SafeVarargs.

Здесь вы только перебираете exampleEntities и получаете из него E. Это соответствует @SafeVarargs.

person newacct    schedule 10.03.2016