不确定如何为该问题加上标题,但会尝试进行解释。我正在尝试使用JPA条件API,并且遇到了一些问题;
我有以下实体;
public class Sword extends Item {}
public class InventoryItem<T extends Item> {}
这就是我正在尝试的工作(除非返回
List<InventoryItem>
,否则我不会编译,但我希望它返回List<InventoryItem<Sword>>
):public List<InventoryItem<Sword>> get() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<InventoryItem> cq = cb.createQuery(InventoryItem.class);
Root<InventoryItem> o = cq.from(InventoryItem.class);
.........
List<InventoryItem> resultList = query.getResultList();
return resultList;
}
我尝试了以下方法;
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<InventoryItem<Sword>> cq = cb.createQuery(InventoryItem<Sword>.class);
Root<InventoryItem<Sword>> o = cq.from(InventoryItem<Sword>.class);
但出现以下错误;
InventoryItem无法解析为变量。
剑无法解析为变量。
最佳答案
InventoryItem<Sword>.class
是Java中的非法表达式。您不能将泛型应用于类文字。即使可以,在返回相同的Class对象时,泛型也会在编译时被擦除。
为了说服编译器将类文字视为通用表达式,您需要将其强制转换为:
CriteriaQuery<InventoryItem<Sword>> cq =
cb.createQuery((Class) InventoryItem.class);
Root<InventoryItem<Sword>> o = cq.from((Class) InventoryItem.class);
要么
CriteriaQuery<InventoryItem<Sword>> cq =
(CriteriaQuery) cb.createQuery(InventoryItem.class);
Root<InventoryItem<Sword>> o =
(Root) cq.from(InventoryItem.class);
...虽然我尚未在本地进行测试,但它们将需要使用
@SuppressWarnings({"unchecked", "rawtypes"})
,因为Java无法在没有泛型的情况下保证强制转换的安全性:您将类型安全放在了自己的手里。(注意:这就是为什么像Guava和Guice这样的库分别引入诸如TypeToken和TypeLiteral之类的概念,以使类文字具有通用类型的原因。)