【问题标题】:Java Generic Type Erasure when using Optional使用 Optional 时的 Java 泛型类型擦除
【发布时间】:2017-09-24 13:41:01
【问题描述】:

类中的定义:

class XXX {
    Map<String, Class> someMap;

    public <K, V>
    Optional<V> get(K key) {
        return Optional.ofNullable(getNullable(key));
    }

    public <K, V>
    V getNullable(K key) {
        //someMap already holds key -> class of V
        String value = DB.fetch(key);

        return gson.fromJson(value, someMap.get(key.toString()));
    }
}

用法:

//xxx is an instance of XXX
Optional<ClassA> valueOpt = xxx.get(key); //this is fine
ClassA value = valueOpt.get(); //this is fine

//The intermediate valueOpt seems redundant, try to bypass it.
ClassA value = xxx.get(key).get(); //this does not work

我的问题:在最后一行,类型信息似乎是可推断的,为什么它不能工作?任何解决方法可以使它在一行中工作?

解决方法总结:
1) xxx.get(key, ClassA.class)
2) (ClassA)xxx.get(key)
3)xxx.&lt;K,ClassA&gt;get(key)

我仍然觉得这些都是解决方法,因为ClassA value = xxx.getNullable(key); 可以工作。

【问题讨论】:

  • 我目前的解决方法是:public &lt;K, V&gt; Optional&lt;V&gt; get(K key, Class&lt;V&gt; valueType); ClassA value = xxx.get(key, ClassA.class).get(); 但实际上没有使用第二个参数 valueType。
  • 失败的原因是类型推断只适用于泛型参数。表达式xxx.get(key).get() 的类型为Object,即使你知道你会从中得到ClassA。如果您必须在一行中完成,那么只需应用一个演员表。 ClassA value = (ClassA) xxx.get(key).get();
  • xxx是如何声明的?如果我声明Map&lt;String,Optional&lt;String&gt;&gt; xxx,那么String value = xxx.get("").get() 有效。如果 xxx 被声明为原始类型,请参阅 stackoverflow.com/a/43076991/1076640
  • 你能分享你对get()的实现吗?我怀疑K 是不必要的,V 是不安全的。
  • 返回类型V不可推演。唯一的保证是您的get 方法将返回Object 的一个实例。

标签: java optional


【解决方案1】:

您可以明确地使用您的方法类型参数:

ClassA value2 = xxx.<String, ClassA>get(key).get();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    相关资源
    最近更新 更多