Exception
and rethrowing is not really catching any Exception
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
}
Exception
IOException
Exception
the code would not have compiled since method is declaring only an IOException
Exception
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 A
bar
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 {}
}