It's not necessary for an overriding method to re-declare all the Exception
s thrown by the superclass method. It's only necessary that it doesn't declare Exception
s to be thrown that aren't thrown by the superclass method.
Section 8.4.8.3 of the JLS elaborates:
More precisely, suppose that B is a class or interface, and A is a
superclass or superinterface of B, and a method declaration n in B
overrides or hides a method declaration m in A. Then:
If n has a throws clause that mentions any checked exception types,
then m must have a throws clause, or a compile-time error occurs.
For every checked exception type listed in the throws clause of n,
that same exception class or one of its supertypes must occur in the
erasure (§4.6) of the throws clause of m; otherwise, a compile-time
error occurs.
If the unerased throws clause of m does not contain a supertype of
each exception type in the throws clause of n, a compile-time
unchecked warning occurs.
That makes sense. Why should a subclass method possibly throw the same Exception
s as the superclass method it overrides? It makes sense for it not to declare additional exceptions, because that would break this scenario:
public class Super
{
public void method() throws FooException {}
}
public class Sub extends Super {
{
public void method() throws FooException, BarException {}
}
Then the usage becomes unclear:
Super sup = new Sub();
try {
sup.method();
}
// But the subclass could (if it were allowed here)
// throw BarException!
catch (FooException e) {}