【问题标题】:Java: is it possible to use a parameterized type into another parameterized type?Java:是否可以将参数化类型用于另一个参数化类型?
【发布时间】:2014-06-21 03:30:39
【问题描述】:

不确定如何命名这个问题,但会尝试解释。我正在尝试使用 JPA 标准 API,但遇到了一些问题;

我有以下实体;

public class Sword extends Item {}
public class InventoryItem<T extends Item> {}

这就是我正在尝试的工作(除非它返回 List&lt;InventoryItem&gt; 但我希望它返回 List&lt;InventoryItem&lt;Sword&gt;&gt;,否则它不会编译):

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 无法解析为变量。

【问题讨论】:

  • 我很确定您可以输入确切的类型,而不是占位符。 class Test&lt;OtherType&gt; { }。我现在不在电脑上,所以测试一下并告诉我
  • 我确实很早就尝试过了,但子类不是一个真正的实体,因此当它尝试执行查询时,使用 CriteriaBuilder 在运行时会失败。
  • 你所说的“不是一个真实的实体”是什么意思?
  • InventoryItem 是一个映射到表“Inventory_Item”的实体,因此该表包含所有玩家-物品关系。如果我扩展它以使类 SwordInventoryItem 扩展 InventoryItem,休眠将失败,因为它不是实体。把它变成一个实体是没有用的,它会制作多个库存表。

标签: java generics jpa type-conversion


【解决方案1】:

InventoryItem&lt;Sword&gt;.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 这样的库分别引入了像 TypeTokenTypeLiteral 这样的概念,以用泛型类型来体现 Class 字面量。)

【讨论】:

  • 不幸的是,这些都不起作用:(我收到编译错误,'Cannot cast to'
  • 很抱歉。我知道我忘记了什么。
猜你喜欢
  • 2016-12-08
  • 2021-09-09
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
相关资源
最近更新 更多