Exception Handling

Handle and Declare Pattern

void f() throws IOException {
    try {
        throw new IOException();
    } catch (Exception e) {  // Not really!
        throw e;             // Due to this guy here!
    }                        // Catching only types declared in method signature
}
// does not compile
void f() throws IOException {
    throw new Exception();
}

How This Feature Prevents Compilation Failures

Imagine the following scenario:

class A extends Exception {}
class B extends Exception {}

void foo() throws A, B {}

void bar() throws A, B {
    try {
        foo();
    } catch (A | B e) {
        throw e;
    }
}
void foo() throws A {}

void bar() throws A, B {     // B is never thrown, but it is legal to declare
    try {
        foo();
    } catch (Exception e) {
        throw e;
    }
}

Exceptions in Inheriting Methods

class MyException extends Exception {}

class A {
    void a() throws MyException {};
}

class B extends A {
    public void a() {}  // no need for throws MyException
}
A a = new B();
try {
    a.a();
} catch (MyException e) { // Must handle exception
    e.printStackTrace();  // Call is on type A not B
}
class A {
    void f() {}
}

class B extends A {
    // this is fine
    // throwing a CheckedException would not compile
    void f() throws RuntimeException {}  
}

🏠