I am working on a small helper that is supposed to invoke arbitrary code (passed in as lambda). The helper should catch certain exceptions, and throw them inside some wrapper. My "own" exceptions should not be wrapped but just re-thrown.
I came up with this code:
@FunctionalInterface
interface Processable<T, X extends Throwable> {
public T apply() throws X;
}
class MyCheckedException extends Exception { ... }
class MyCheckedExceptionWrapper extends MyCheckedException { ... }
public class MyExceptionLogger<T, X extends Throwable> {
public T process(Processable<T, X> processable) throws MyCheckedException {
try {
return processable.apply();
} catch (MyCheckedException thrown) { // this line isn't accepted
throw thrown;
} catch (Exception | LinkageError thrown) {
throw new MyCheckedExceptionWrapper(thrown);
} catch (Throwable thrown) {
... just log
return null;
}
}
}
The above gives a compile error:
Unreachable catch block for MyCheckedException. This exception is never thrown from the try statement body MyExceptionLogger ...
In other words: although apply()
is defined to throw some X extends Throwable
I can't catch a specific checked exception when invoking that method.
I know that I can get to working code by catching Throwable, to then use instanceof
checks - but I would like to understand why it is not possible to have a try/catch as outlined above.
A checked exception must be handled either by re-throwing or with a try catch block, whereas an unchecked isn't required to be handled.
Generally, you catch many exceptions, generalize them into one and throw it.. So that all similar exceptions can be handled in the same way..
What happens if an exception is not caught? If an exception is not caught (with a catch block), the runtime system will abort the program (i.e. crash) and an exception message will print to the console.
throws: The throws keyword is used for exception handling without try & catch block. It specifies the exceptions that a method can throw to the caller and does not handle itself. 5. finally: It is executed after the catch block.
This behavior is specified in section 11.2.3 of JLS:
It is a compile-time error if a catch clause can catch checked exception class
E1
and it is not the case that the try block corresponding to the catch clause can throw a checked exception class that is a subclass or superclass ofE1
, unlessE1
isException
or a superclass ofException
.
MyCheckedException
fits the description of E1
class above, because it is not declared in the generic declaration of processable.apply()
, and it is not Exception
or one of its superclasses. The compiler knows only that the method can throw a Throwable
, so MyCheckedException
is not declared.
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