4

Given:

static class A {
    void process() throws Exception { throw new Exception(); }
}
static class B extends A {
    void process() { System.out.println("B "); }
}
public static void main(String[] args) {
    A a = new B();
    a.process();
}

In this question, when I call a.process(), it will give me a compile time error, saying, "Unhandled exception must be handled". But, if the parent method is throwing any checked exception, its not necessary to handle that exception in the child if we are overriding the parent's implementation.

Why is the exception still checked?

gvlasov
  • 18,638
  • 21
  • 74
  • 110
Amit2311
  • 93
  • 1
  • 7
  • possible duplicate of [Java. Removing throws declaration in overriden method, yet compiler want a try/catch blok when invoking.](http://stackoverflow.com/questions/9413599/java-removing-throws-declaration-in-overriden-method-yet-compiler-want-a-try-c) – Raedwald Sep 16 '14 at 06:55
  • 1
    This is an exact duplicate of http://stackoverflow.com/questions/17170583/why-we-must-handle-exception-for-method-not-throwing-exceptions it is asking about the same example code – Raedwald Sep 16 '14 at 06:58

4 Answers4

7

The point is that the compiler doesn't know that you're calling an overridden method which doesn't throw any checked exceptions. When it sees:

a.process();

it doesn't "know" that the value of a is actually a reference to an instance of B. It could be a reference to an instance of A (or an instance of another subclass), which would throw the exception.

If you want to use subclass-specific signatures, you need:

B b = new B();

instead. Then when the compiler sees

b.process();

it will look at how the method is declared in B, not how it's declared in A.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2

If parent method throws exception then a Child :

  1. Doesn't need to throw any exception.
  2. Can not throw any broader exception than declared by the parent .
  3. Can throw any Runtime exception: obviously in java we don't declare them in throws clause but i am mentioning it just for the sake of your knowledge.

In your case you are declaring an object of type A that can refer to

  1. any object of class A
  2. or any object of it's subclass

So when you call a.process(); then compiler check for the method definition declared in A and since method process in A declare that it throws exception , so compiler complain about the unhandled exception

user207421
  • 305,947
  • 44
  • 307
  • 483
sol4me
  • 15,233
  • 5
  • 34
  • 34
0

Well, Jon Skeet (as always :P ) has given a really good answer. Adding my two cents here.

 A a = new B();
 a.process();

In the above lines, the compiler just looks up the class A (reference) and checks whether the method process() is present or not. It also checks for the signature and verifies whether the exceptions thrown by the method are handled correctly when it is being called.

The compiler here, just sees process() of class A. It doesn't even check if class B defines/declares process(). Which process() to call is decided by the JVM. So, the compiler goes with what it sees, class A's process throws exception, so you have to handle it.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • 1
    The OP's point is that `B.process()` *doesn't* declare that it throws any exception. – Jon Skeet Sep 16 '14 at 06:29
  • Is it Static class dats why this problem coming or just before overiding it will check class A method after that it will override? – Amit2311 Sep 17 '14 at 15:29
0

You get the compile error because you have declared your object a to be of type A. The declaration of the .process() method at the A level says it could raise an exception, so the compiler says you should handle it. The compiler has no way of knowing (*) that at the time the invocation will occur, your object a is actually of a subtype of A.

Contrary to what you say, it is perfectly possible for an overriding method to not throw any of the exceptions declared possible at the supertype level (or just some of them but not all, or some proper subtypes of those exceptions declared possible at the supertype).

(*) code can get a lot more complex than just these simple two statements.

Erwin Smout
  • 18,113
  • 4
  • 33
  • 52