不确定如何标题这个问题,但会尝试解释。我正在尝试使用 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 无法解析为变量。
Sword 无法解析为变量。
最佳答案
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 这样的概念,来体现具有泛型类型的类文字。)
关于Java:是否可以将一个参数化类型用于另一个参数化类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23462163/