链接 Optional.orElseThrow

Chaining Optional.orElseThrow

我有一段代码是这样的:

return getObject()
    .map(obj -> obj.getNullableField())
    .orElseThrow(() -> new IllegalStateException("Object not found!"));

目前,当给定的 Object 不存在时,我会抛出异常。

现在我还需要检查 ObjectnullableField 是否存在。

一个明显的解决方案可能是这样的:

var fieldVal = getObject()
    .map(obj -> obj.getNullableField())
    .orElseThrow(() -> new IllegalStateException("Object not found!"));

  return Optional.ofNullable(fieldVal)
     .orElseThrow(() -> new IllegalStateException("Field is not present"));

但我想在同一个功能链中实现它...

我错过了什么?

可以直接在同一个链中实现,会抛出不同的异常。现在,它的可读性当然不如您的第一个解决方案,因此您需要权衡取舍。

return getObject().map(obj -> Optional.ofNullable(obj.getNullableField())
                                      .orElseThrow(() -> new IllegalStateException("Field is not present")))
                  .orElseThrow(() -> new IllegalStateException("Object not found!"));

而不是嵌套,我会建议一个简单的序列来解决这个问题:

var value = getObject()
        .orElseThrow(() -> new IllegalStateException("Object not found!"));

return Optional.of(value) // ensured value check already
        .map(CustomObject::getNullableField) // takes care ofNullable
        .orElseThrow(() -> new IllegalStateException("Field is not present"));

我建议完全放弃 Optional 方法或至少只在开始时使用它(假设 getObject() 无法更改):

var value = getObject()
    .orElseThrow(() -> new IllegalStateException("Object not found!"));

var field = value.getNullableField();
if(field == null) {
    throw new IllegalStateException("Field is not present");
}
return field;

这并没有引入新的 Optional 包装器,因此您可以 "fluent" 并在一行/语句中完成所有操作。