Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I have a catch for a checked exception for a call that throws a generic?

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.

like image 950
GhostCat Avatar asked Aug 22 '17 11:08

GhostCat


People also ask

Can we use catch statement for checked exceptions?

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.

Can we catch and throw the same exception?

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 your program does not catch an exception?

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.

How do you throw an exception without catching it?

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.


1 Answers

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 of E1, unless E1 is Exception or a superclass of Exception.

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.

like image 133
Sergey Kalinichenko Avatar answered Sep 19 '22 15:09

Sergey Kalinichenko