可选图,orElse必须返回相同的类型

问题描述 投票:-1回答:1

我有此代码:

Object s = ofNullable(resp).map(obj1::get1).orElse(ex.getMessage());
obj1::get1 returns Object and ex.getMessage returns String

我在此遇到编译器错误:可选类型的方法orElse(capture#10-of?)不适用于参数(字符串)

但是我可以不使用可选内容来编写它,但效果很好:

if (resp!= null) {
    s = obj1.get1();
 } else {
    s = ex.getMessage();
 }
java null optional
1个回答
0
投票

问题源于Java如何进行类型推断。

方法参考(和lambda)是polyexpressions。这意味着相同的表达式可以具有不同的类型,具体取决于使用的位置。

所以,您的多表达式:

ofNullable(resp).map(obj1::get1)

具有some类型。

如果要在分配上下文中使用它:

Optional<Object> opt = ofNullable(resp).map(obj1::get1);

然后就可以了,因为类型推断约束允许可选参数的类型参数为Object

但是,如果将表达式用作其他方法调用的接收者:

ofNullable(resp).map(obj1::get1).orElse(...)

然后Java首先推断ofNullable(...).map(...)的类型,然后进行到orElse

很明显,obj1.get1(resp)不会像您声明的那样返回Object,而是返回一些通配符类型。这是可选的推断类型:Optional<some wildcard>。因此,orElse的参数也必须为some wildcard类型。唯一可能的值是null

有几种解决方法:

  • 您可以将ofNullable(...).map(...)的结果显式分配给类型为Optional<Object>的变量,然后在该变量上调用orElse
  • 您可以强制转换为Optional<Object>

    ((Optional<Object>) ofNullable(...).map(...)).orElse(...)
    
  • 您可以改用lambda,然后将结果转换为Object

    ofNullable(...).map(r -> (Object) ...).orElse(...)
    

或者您可以保持简单,而不要尝试使用Optional

Object s = (resp != null) ? obj1.get(resp) : ex.getMessage();
© www.soinside.com 2019 - 2024. All rights reserved.