我下面的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参数示例产生的潜在堆污染
在这种情况下使用
@SafeVarargs
注释是否安全?据我了解,只要不使用
Object[]
初始化本地exampleEntities
,就可以了。但这似乎不对。此方法类似于
java.util.Collections.addAll
中提到的方法the Java Specification §9.6.3.7,该方法用@SafeVarargs
注释。This answer讨论警告,说一般而言,以下代码是安全的:
@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
注释不安全的情况? 最佳答案
是的,您可以使用@SafeVarargs
。是否可以使用@SafeVarargs
取决于如何使用varargs参数exampleEntities
。如果依靠其实际运行时类型为E[]
,则不能使用@SafeVarargs
,但是如果仅依靠其元素的类型为E
,则可以使用@SafeVarargs
。
在这里,您仅遍历exampleEntities
并从中获取E
。这与@SafeVarargs
一致。