The answer is easy:
You cannot throw an exception in overwriten methot in class B, if original method in class A doesn't "support" throwing it.
Let's say you will call your method from somewhere else:
A a = new A();
a.charlie();
Since method charlie
in class A
doens throw any exception, it's OK. If that method would throw an exception, you would have to write
A a = new A();
try {
a();
} catch(IOException ex) { //or any other exception
//oh noes
}
But now it gets complicated, because something called class polymorphism comes to make your work mode complicated:
private A getA() {
return new B(); //this will work since B extends A
}
private void doSomething() {
A a = new A(); //you could also write A a = new B();
a.charlie();
}
Now this code takes a
as it was object from class A
and it has method charlie()
with no thrown exceptions. Even though a
is object from class B
, compilator doesn't know it and doesn't look what exceptions are thrown in methods in class B
, because a
is from class A
, at least from compilator's view.
And thats why method charlie()
in class B
must be same(input parameters, return type and thrown exceptions) as in class A
, you can only change body of the method.
However, you can still throw NullPointerException or UnsuportedOperationException, because these belong to RuntimeException, and every existing method in Java automaticly thorws RuntimeException, so you can throw any of these any time you want.