Win a copy of Design for the Mind this week in the Design forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Exception Handling with Inheritance

 
Jeena Jeen
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,
Can anybody help me to understand how Exception handling works with Inheritance.
For instance i have following code

class Parent
{
int getInt(String arg) throws Exception {return 42;}
}
class child extends Parent
{
int getInt(String arg){return Integer.parseInt(arg);}
}

I was expecting Compiler error because overridden method getInt() in "child" class should either same exception i.e. "Exception" or any subclass of "Exception".
Why the code runs perfectly fine?
 
Himalay Majumdar
Ranch Hand
Posts: 324
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"Exception" or any subclass of "Exception..actually means..The subclass must not define any exception tougher than the one in SuperClass. So if you dont declare any exception in SubClass it must run perfectly fine.
 
Kavita Tipnis
Ranch Hand
Posts: 177
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Mumtaz Khan
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As inheritance allows a class to be a subclass of a superclass and inherits its public and protected variable and methods.
with respect to overriding a method, subclass method can not throw new or broader checked exception than superclass's method declaration. However it can throw fewer or narrower checked exception or any runtime exception.Also it may not even declare an exception that is declared in superclass's method.
With respect to overload, superclass method can throw different exceptions.
 
Jeena Jeen
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes thats right. but whats the point in having no exception in subclass we won;t be able to use the overriden mehod.
As mentioned by Kavita when we try to use getInt() from "child" there will be an exception.
So that means this scenario is valid as long as we do not use the overridden method.
 
Kavita Tipnis
Ranch Hand
Posts: 177
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The subclass is not bound to handle the exception, it can pass it down further the inheritance tree,
but the last method on the call stack has to handle the exception no matter what.
If you have K&B go through 'Propagating Exceptions' on Page 362.
It has a great example.

 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's better to be a little more precise. When you declare a checked exception in a method (via a throws clause,) then any code that calls that method must either handle that potential exception, or declare it itself (via a compatible throws clause.) By compatible I mean that it must declare that it throws that exception, or any supertype of that exception.

Now, assume that you have class A with a method() that declares that it throws ExceptionA (where ExceptionA is checked.) Now imagine a subclass of A, let's call it B. If B overrides method(), it is not required to declare any exceptions at all. But it can not declare broader checked exceptions (or checked exceptions that do not pass the Is-A test for the declared exceptions in the method of the superclass) than the ones declared by method(). In our case, B.method() could declare checked exceptions that are either ExceptionA, or subtypes of ExceptionA.

Why is that so? Because checked exceptions are checked by the compiler (the compiler must verify that you either declare or catch any checked exceptions that may be thrown by your code.) Now, the compiler doesn't think polymorphically, it only looks at the declared type of a reference. So if you allowed B.method() to throw, say ExceptionX (where ExceptionX is a checked exception that is not a subclass of ExceptionA) and you did this:
A b = new B();
try {
b.method();
}
catch (ExceptionA ea) {
}

At this point, the compiler would see that you are calling method() on a reference of type A, which may throw ExceptionA exceptions. It would say: OK, you are handling a potential exception of type ExceptionA.

But what if B.method() (the method that is called polymorphically at runtime) actually throws ExceptionX? Then your code would not handle that and it would fail.

That's why you can't throw broader checked exceptions (or any checked exceptions that are not subtypes of the exceptions declared in the overridden method.) Because the compiler is limited to verify handling/declaration of exceptions based on the type of references.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic