Let's say there's an Optional
optString. Now if I use it as below:
optString.ifPresent({
//some statements
}, () -> throw new Exception());`, it fails to compile.
Why do I've to wrap the throw new Exception()
inside curly braces {}
.
Why can't I simply do () -> throw new Exception
.
Why is the compiler treating throw
and new
as some states that should be in a block?
In IntelliJ it fails with compilation errors: expected ) expected { expected;
and Unexpected token
A complete example:
class OptionalTest {
Optional<String> testString() {
return Optional.empty();
}
void getString() {
var optStr = testString();
optStr.ifPresentOrElse(s -> {
}, () -> throw new RuntimeException());
}
}
You cannot simply throw
in the lambda expression the way you did since a lambda body is either a single expression or a block. The throw
is a statement.
You have to wrap throwing an exception into the block:
optStr.ifPresentOrElse(
str -> /*do something*/,
() -> { throw new RuntimeException(); });
It is also worth mentioning Optional#orElseThrow
which is designed to actually throw an exception. The only argument passed into the Supplier
is the way to instantiate the exception, the method just takes it and throws instead of you if the Optional
is empty.
optStr.orElseThrow(() -> new RuntimeException());