Exception and rethrowing is not really catching any Exceptionvoid 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
}
Exception
IOExceptionException the code would not have compiled since method is declaring only an IOExceptionException
IOException is narrow compared to Exception// 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;
}
}
catch (Exception e), instead we used catch (A |B e)B anymore
void foo() throws Abar is now catching B which is never thrown in foo
catch (Exception e) where we still have throws A, B in method bar, we are only left with throws B which is never thrown in bar
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;
}
}
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 {}
}