Why is it said: "Checked exceptions are not forwarded in calling chain (propagated)"?

794 Views Asked by At

For unchecked (runtime) exceptions it is understandable. They are literally propagated through stack. But why is it said that checked exceptions are not? Yes, we have to declare (throws) or handle them (try-catch), but why is it not called 'propagating' in this case? Let me give you basic example:

public class Main {
    void m() throws IOException {
        throw new java.io.IOException("device error");//checked exception
    }
    void n() throws IOException {
        m();
    }
    void p(){
        try{
            n();
        }catch(Exception e){System.out.println("exception handled");}
    }
    
    public static void main(String args[]){
        new Main().p();
    }
}

In my opinion I just did a 'chaining' that worked fine. So why do the docs say "by default checked are not propagated"?

2

There are 2 best solutions below

0
On BEST ANSWER

by default checked are not propagated

I believe the source of this is here.

This is unusual terminology. I suspect what is meant by that statement is that you can't just write:

void m() {
    throw new IOException("device error");//checked exception
}
void n() {
    m();
}
void p(){
    try{
        n();
    }catch(Exception e){System.out.println("exception handled");}
}

because the exception isn't "propagated" from m() to n() to p(), because it's a checked exception, so this code doesn't even compile.

It would be "propagated" from m() to n() to p() by this code if it were an unchecked exception.

You have to explicitly propagate the exception, if that's what you want:

void m() throws IOException { ... }
void n() throws IOException { m(); }

The alternative to such propagation is that you handle it inside the method. The point is, you have to choose what to do with it.

1
On

There is actually no difference at all between the behaviour of checked and unchecked exceptions at runtime.

Checked exceptions are merely a subset of all exceptions, for which the compiler decides to look at them and see whether they are either explicitly declared as thrown or caught. If not, it's an error.

If you can somehow hack the compiler to skip this check, it behaves exactly like a runtime one.

Given the runtime semantics are identical, it does not make sense to say one is propagated and the other isn't.