可选映射和orElse必须返回相同的类型



我有这个代码:

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

我得到一个编译器错误:

The method orElse(capture#10-of ?) in the type Optional<capture#10-of ?> is not applicable for the arguments (String)

但我可以在没有可选的情况下写这篇文章,它运行良好:

Object s = resp != null ? resp.getBody() : ex.getMessage();

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

方法引用(和lambdas(是多表达式。这意味着同一个表达式可以有不同的类型,这取决于它在哪里使用。

所以,你的多表达:

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

具有某种类型。

如果你要在任务上下文中使用它:

Optional<Object> opt1 = ofNullable(resp).map(obj1::get1);
Optional<?> opt2      = ofNullable(resp).map(obj1::get1);

那么这两者都可以,因为类型推断约束允许option的类型参数与变量的类型参数匹配。

但是,如果您将表达式用作另一个方法调用的接收器:

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

然后Java首先推断ofNullable(...).map(...)的类型(它不再是多表达式(,然后进行到orElse

很明显,obj1.get1(resp)并没有像您所声称的那样返回Object,而是返回一些通配符类型。这是可选项的推断类型:Optional<some wildcard>。那么orElse的参数也必须是some wildcard类型;其唯一可能的值是CCD_ 8。

有很多方法可以解决这个问题:

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

  • 你可以投射到Optional<Object>:

    ((Optional<Object>) ofNullable(...).map(...)).orElse(...)
    
  • 您可以显式映射到Object:

    ofNullable(...).map(...).map(Object.class::cast)
    
  • 您可以使用lambda,并将结果强制转换为Object:

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

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

Object s = (resp != null) ? obj1.get(resp) : ex.getMessage();

相关内容

  • 没有找到相关文章

最新更新