3

我有这个代码:

List<NumericConfig> results = null;

@SuppressWarnings("unchecked")
results = query.getResultList(); // query is JPA named query

但我收到此错误:

结果未被识别为有效类型

但这段代码有效:

@SuppressWarnings("unchecked")
List<NumericConfig> results = query.getResultList(); // query is JPA named query

为什么我的第一个代码不起作用?

4

1 回答 1

4

像这样的注解

@SuppressWarnings("unchecked")

只能应用于包、类、类成员(包括enum值)或变量声明。它们不能应用于任意陈述。

JLS 的第 9.7 节

注释可以在任何声明中用作修饰符,无论是包(第 7.4 节)、类(第 8 节)、接口、字段(第 8.3 节、第 9.3 节)、方法(第 8.4 节、第 9.4 节)、参数、构造函数(第 8.8 节) ,或局部变量(§14.4)。

由于它出现在方法体内,编译器已经排除了(包,类,成员)声明,因此期望在它之后有一个变量声明。变量声明以类型开头,因此它解释results为类型名称,然后意识到它不是,并抱怨它,然后才意识到这= query...不是有效的变量名称和初始化程序。


我认为

List<NumericConfig> results

应该是

List<? extends NumericConfig> results

因为您可能不知道查询使用的确切实现类型,并且无论如何都无法有效地添加到结果列表中。


我不会将注释添加到整个方法中,因为这可能会抑制您(或以后的代码维护者)不确定是否安全的其他未经检查的分配。

您可以将作业分成两部分

// This is type-safe because query is known to be a JPA named query.
// We use ? extends because query may be a more specific concrete type,
// and because we cannot add to the list owned by query.
@SuppressWarnings("unchecked")
List<? extends NumericConfig> resultListTyped = query.getResultList();
results = resultListTyped;

或者,根据我的喜好,您可以将注释附加到静态方法

results = unpackResultList(query, NumericConfig.class);

和其他地方

@SuppressWarnings("unchecked")
private static <T>
List<? extends T> unpackResultList(Query query, Class<T> resultType) {
  List<T> results = query.getResultList();
  // A quick and dirty sanity check of just the first value.
  assert results.isEmpty() || resultType.isInstance(results.get(0));
  return results;
}

后一种选择的好处是也适用于 Java 5。

于 2013-04-12T16:42:07.467 回答