不确定如何标题这个问题,但会尝试解释。我正在尝试使用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解析为变量。
无法将剑解析为变量。
答案 0 :(得分:0)
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这样的概念,以体现具有泛型类型的类文字。)