【问题标题】:Covariance casting with generics使用泛型进行协方差转换
【发布时间】:2012-11-16 02:31:09
【问题描述】:

在 Java 中,如果我有以下信息:List.class, Map.class, Integer.class,以及某个 Object 的实例 foo。是否可以将foo 转换为List<Map<Integer, Integer>>?我想不是因为类型擦除,而是想知道是否有其他方法可以实现类似的效果。

编辑:提供更多上下文。我正在编写一个能够接受查询(由对象和指标组成)并输出所需指标的应用程序。一个例子是“列表中元素的总和”。客户端需要编写一个提供程序,将自身注册到应用程序并广播它能够为某些对象类型提供某种度量类型(例如,列表的总和)。该应用程序在收到查询后将匹配正确的提供程序并在其上调用calculate 方法。

没有泛型,这很简单。任何对象实例的规范类型都是它的类。因此,我会将查询中的对象视为Object,然后使用其class,找到能够提供此对象实例的提供程序。指标也类似。

现在引入泛型...假设我将度量 f 定义为列表中元素的总和(如果元素是 Integer)和乘积(如果元素是 Double)。我需要 2 个提供者,一个提供 List<Integer>,另一个提供 List<Double>。但是由于类型擦除,我不能直接使用规范类型class。所以我存储了涉及的类(List.classInteger.classList.classDouble.class)并使用类元组匹配提供者。

因此在calculate 方法中,我需要执行从Object 到提供程序处理的适当类型的协变转换。

也许我对问题采取了错误的方法?

【问题讨论】:

  • 不清楚你的意思是你在编写代码时知道它是 List、Map 和 Integer,在这种情况下你可以只做一个常规的旧转换,或者如果它是三个 Class<?>您不知道的对象,在这种情况下您是正确的,这是不可能的。
  • 请提供更多背景信息。谁创建实例List<Map<Integer, Integer>>?如果您控制new 语句,则可以在其中放置其他信息,以便可以进行这种类型的转换。你能控制它吗?

标签: java generics casting


【解决方案1】:

你会得到最接近的是:

List<Map<Integer, Integer>> fooList = List.class.cast(foo);

由于不安全的转换和原始类型的使用,它会产生编译器警告,但它实际上是安全的(如果你知道你的 Object 包含它所说的内容)。

【讨论】:

  • 但在这种情况下,与“传统”铸造相比没有优势,还是有?
  • 不,如果你在编译时没有类型,你会使用这个版本
  • @SeanPatrickFloyd thx,我实际上正在做你提到的事情。不喜欢编译器警告,所以想知道是否有其他我不知道的方法来做到这一点。
【解决方案2】:

不是没有收到警告,AFAIK。

List<Map<Integer, Integer>> bar = (List<Map<Integer, Integer>>) foo;

【讨论】:

    猜你喜欢
    • 2020-11-20
    • 2011-02-09
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多