是否可以仅在方法中返回Optional值,但是如果它不仅仅是继续正常的方法流程。像这样:
public Message processMessage(Message message) {
// ErrorMessage is subclass of Message; only returned if validator found some violations, otherwise empty optional
Optional<ErrorMessage> error = validator.validate(message);
if (error.isPresent()) return error.get();
// returns different possible subclasses of Message
return service.processMessage(message);
}
有没有更漂亮的方法来写这个?
答案 0 :(得分:1)
我只会选择Optional.orElseGet
并在两者之间进行明确的演员:
public Message processMessage(final Message message) {
return validator.validate(message)
.map(Message.class::cast)
.orElseGet(() -> service.processMessage(message));
}
答案 1 :(得分:1)
您的问题确实是返回类型不匹配。 orElseGet
仅在供应商返回Optional
类型的子类型时才有效。
要解决此问题,您可以先强制转换为父类型:
return error.<Message>map(m -> m).orElseGet(() -> service.processMessage(message));
或等效地:
return error.map(m -> (Message) m).orElseGet(() -> service.processMessage(message));
答案 2 :(得分:0)
我目前无法测试它,但它可能会给你一个想法,也许你可以实现类似下面的内容
return Optional.ofNullable(message)
.map(validator::validate)
.orElseGet(service::processMessage)
答案 3 :(得分:0)
查看该代码段,validate
上的validator
方法似乎没有正确的返回类型。考虑使用例如io.vavr.control.Either
或io.vavr.control.Validation
monad。看一下validate
的可能签名:
Either<SpecificError, ? extends Message> validate(Message message);
现在map
和fold
组合器可以像这样使用:
validator
.validate(message)
.map(message -> service.processMessage(message))
.fold(error -> new ErrorMessage(error), success -> success); // the left function can be replaced by Function.identity()
获得Message
。