我有此代码:
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如何进行类型推断。
方法参考(和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();