I keep writing specific exception throwers in the case the Optional is absent.
For instance:
Optional<?> optional = ...;
if (!optional.isPresent()) {
throw new MyException();
}
Object result = optional.get();
I find this code not very fluent, especially the use of the bang (!). I'd rather like writing something like:
Optional<?> optional = ...;
Object result = optional.orThrow(MyException.class);
Is there such a shortcut in Guava that I haven't found yet?
Returns the value of each present instance from the supplied optionals , in order, skipping over occurrences of absent() . Returns a string representation for this instance. If the instance is present, it is transformed with the given Function ; otherwise, absent() is returned.
Introduction : Optional is an immutable object that may contain a non-null reference to another object. Each instance of this type either contains a non-null reference, or contains nothing, in which case we say that the reference is absent. It is never said to contain null.
Speaking as a Guava developer, let me try to unpack the logic here. Responding both to the original question, and the comment thread directly on the question:
It is absolutely the case that we try to force Guava users to respect our standards of good programming habits. (Our standards are strongly influenced by e.g. Effective Java.)
That said, I agree that there are perfectly good use cases for the behavior you're referring to in this particular question: "if absent, throw an exception." Perhaps you're implementing a class that can be accessed both ways -- one method with an Optional return value, and one method that assumes that the value will always be present, throwing an exception otherwise. The Deque interface, for instance, provides special-valued and exception-throwing versions of peek, poll, and offer.
All that said, to the best of my understanding, the True Guava Way to do this is...
if (value.isPresent()) {
return value.get();
} else {
throw new MyException();
}
The "orThrow" method you propose requires reflection (!!), doesn't let you customize the exception with a useful message, etc. The "normal way" is perfectly readable and more efficient.
Sometimes Guava doesn't provide explicit support for things because for those use cases, we think it's best done just the "normal way." I think this is the case here.
It is worth nothing that Java 8's Optional
has an orElseThrow(Supplier)
method that allows the requested behavior.
It is used like this:
Optional<Object> reference = Optional.empty()
reference.orElseThrow(MyOwnException::new); // Throws a new MyOwnException
Furthermore, a method in Java 10 was added, orElseThrow()
, which throws a NoSuchElementException
if no value is present.
Optional<Object> reference = Optional.empty();
reference.orElseThrow(); // Throws a new NoSuchElementException
Here's another way to do it without additions to Guava:
Object result = optional.or(new Supplier() {
public Object get() {
throw new MyException();
}
});
MyException has to be unchecked, but this does allow you to pass arguments to its constructor. And of course if you're doing it a lot you can store the Supplier somewhere and use it each place you need it.
Object result = optional.or(SomethingIsMissing.INSTANCE);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With