I looked at the Optional
class method orElseThrow
out of curiosity and I got confused of its signature. I didn't understand why it has to be declared as it is. So, I did an experiment with a copy of the original orElseThrow
method and my simplified variant:
public class Main<T> {
//This is original signature of Optional.orElseThrow method
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X{
throw exceptionSupplier.get();
}
//This is my attempt to simplify it but it doesn't work without try-catch block
public T orElseThrow2(Supplier<Throwable> exceptionSupplier) throws Throwable{
throw exceptionSupplier.get();
}
public static void main(String[] args){
Main<Object> m = new Main<Object>();
m.orElseThrow(() -> new RuntimeException("ha")); //no warnings/errors shown
m.orElseThrow2(() -> new RuntimeException("sad")); //"Unhandled exception: java.lang.Throwable"
}
Why my method is not accepted without a try-catch
block?
Why extending Throwable
as in the original method doesn't require a
try-catch
block even though original method throws a Throwable
object?
Because all the compiler knows about your method is that is throws a Throwable. Since the Throwable could thus be a checked exception, you're forced to declare it in the throws clause or to catch it.
Because the compiler knows that the method throws X, where the generic type X is inferred as RuntimeException
: () -> new RuntimeException("ha")
is a Supplier<RuntimeException>
. And runtime exceptions, by definition, are unchecked exceptions that don't need to be declared in the throws clause.
To clarify one step further:
Having a generic exception (throws X) is giving flexibility.
If you return a checked exception while using the first signature:
m.orElseThrow(() -> new Exception("ha"));
The compiler gives the error (Unhandled Exception) as well because it knows that some checked exceptions might be thrown. However, supplying RuntimeException gives the sign to the compiler that it is an unchecked exception.
On the other hand, in your custom method, you are making sure that it will always throw Throwable
, which requires handling.
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