1

I'm preparing myself for a test, and I found this code that I don't understand.

If I override a method just like this, it can't compile. Ok, fair enough. I have to throw a parent exception in line 2, (like throws Exception) and it would work just fine... But, why is it possible then, to change line 7 with public void charlie throws NullPointerException?? This would compile just fine, because I'm still not throwing anything in line 2.

    1.public class A {
    2.  public void charlie() 
    3.  {
    4. 
    5.  }
    6.  class B extends A{
    7.      public void charlie() throws IOException
    8.      {}
    9.  }
    10.}
rgettman
  • 176,041
  • 30
  • 275
  • 357

3 Answers3

8

NullPointerException is an unchecked exception (because it extends RuntimeException). It never needs to be declared, and it can be declared without affecting anything else.

You should revise your understanding of checked and unchecked exceptions.

The Java exceptions tutorial is probably a reasonable starting point.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • You're right, IOException is a checked exception, therefor it needs to establish a policy, and NullPointerException es an unchecked exception so it does not need to. :) –  May 08 '13 at 20:19
1

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.

kajacx
  • 12,361
  • 5
  • 43
  • 70
0

IOException is an exception that must be caught; you can't call a method that throws it without a try-catch block.

However, now consider the following:

A myObject;
myObject = new B(); // legal - polymorphism
myObject.charlie();

One might expect that this would not throw an error, because A doesn't have a throws declaration, but B does. Therefore, this code cannot be legal.

A method may have fewer thrown exceptions declared, but not more.

wchargin
  • 15,589
  • 12
  • 71
  • 110