With release of Java-11
, Why do we have orElseThrow
with optionalLong
/ OptionalDouble
and other Optional Types
when we can directly check if a number is not null or not equals to a specific number.
Also, we were doing null checks which were better than throwing an Exception?
May be not able to visualize the real use of optionalTypes
and orElseThrow
.
Javadoc for orElseThrow
.
In a nutshell, the Optional class includes methods to explicitly deal with the cases where a value is present or absent. However, the advantage compared to null references is that the Optional class forces you to think about the case when the value is not present.
public final class OptionalLong extends Object. A container object which may or may not contain a long value. If a value is present, isPresent() returns true . If no value is present, the object is considered empty and isPresent() returns false .
Optional is intended to provide a limited mechanism for library method return types where there needed to be a clear way to represent “no result," and using null for such was overwhelmingly likely to cause errors.
Core Java bootcamp program with Hands on practice Optional is a container object used to contain not-null objects. Optional object is used to represent null with absent value. This class has various utility methods to facilitate code to handle values as 'available' or 'not available' instead of checking null values.
I randomly chose a method from com.google.common.io
API which demonstrates the use of Optional<Long>
. They use own Optional
type, but the concept is identical.
@Override
public Optional<Long> sizeIfKnown() {
if (file.isFile()) {
return Optional.of(file.length());
} else {
return Optional.absent();
}
}
Due to the absence of OptionalLong
, they are auto-wrapping file.length()
, which returns a long
, into an Optional<Long>
. They don't want sizeIfKnown
to throw an exception. They don't want sizeIfKnown
to introduce a magical return value which would indicate the absence of a value.
Instead, they want to say "we return a long
, or nothing".
With Java 11, it would look a bit cleaner, and a bit simpler
@Override
public OptionalLong sizeIfKnown() {
if (file.isFile()) {
return OptionalLong.of(file.length());
} else {
return OptionalLong.empty();
}
}
Regarding orElseThrow
, it's relatively old feature introduced in Java 8 to control execution flow in a functional manner. It does exactly what you described: a null
check and a throw
statement.
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
Why do we have orElseThrow with optionalLong / OptionalDouble when we can directly check if a number is not null or not equals to a specific number.
Not really, Optional
s are designed for return types, not for checking input parameters.
In the later cases, checking not null or range validity (for primitives) makes more sense.
Besides, these features are not new. Java 8 already introduced these functions.
To illustrate the interest of OptionalLong.orElseThrow()
, suppose a case where you search a long
id from a method but that id may not be found.
Here is a code that handles the not found value case.
Without OptionalLong
, you should choose an arbitrary long value to convey the not found result :
long id = compute(); // returns -1. By hopping that it not a valid id...
Then, from the client side, you have to dig into the implementation of compute()
to know if the id value can be empty and whether is the case, which value represents the emptiness.
And at last you could write that :
if (id == -1){
throw new IllegalArgumentException("the id is mandatory");
}
Suppose that tomorrow -1
be a valid id, so you should change both the implementation and the client code to be aware of it : not maintainable at all and very error prone.
With OptionalLong
the approach is much more robust :
OptionalLong optId = compute(); // returns OptionalLong.empty();
As a client of compute()
you know that the id may be empty (Optional
semantic) and you know also how to handle it in a standard way: the Optional` unwrapping functions.
long mandatoryId = optId.orElseThrow( ()-> new IllegalArgumentException("the id is mandatory");
Here OptionalLong
or even Optional<Long>
provides a triple advantage (about the difference between them I advise the excellent answer of Nishant) :
-1
approach).Optional
and its functions)But in a general way, Optional
s with Object
s contained in provides "only" these two advantages :
Optional
and its functions)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