Consider the following simple example:
Optional.empty().orElseThrow(this::exceptionSupplier);
IntelliJ generates a method like the following for the supplier, tough it does not compile!
private <X extends Throwable> X exceptionSupplier() {
return new RuntimeException();
}
Incompatible types. Required: X Found: java.lang.RuntimeException
If i change the signature to the following it works.
private Exception exceptionSupplier() {
return new RuntimeException();
}
Is it correct that the compiler cannot determine the correct type for X
?
If the first example were to work, consider the following:
Supplier<InterruptedException> s = this::exceptionSupplier;
This would then fail with a ClassCastException
if you called it like so:
InterruptedException e = s.get();
This is because X
is determined at the call site. There is an implicit cast inserted by the compiler:
InterruptedException e = (InterruptedException) s.get();
But, of course, s
returns you a RuntimeException
, which can't be cast to InterruptedException
.
If you want to return a RuntimeException
, make the return type of the method RuntimeException
, no type variable required.