2

just look at program below..

import java.io.*;
import java.rmi.*;
class class1
{
  public void m1() throws RemoteException 
{
  System.out.println("m1 in class1");
}
}


class class2 extends class1
{
  public void m1() throws IOException
{
 System.out.println("m1 in class2");

}
}


class ExceptionTest2
{
  public static void main(String args[])
  {
    class1 obj = new class1();
  try{
       obj.m1();
     }
catch(RemoteException e){
       System.out.println("ioexception");
     }

  }
}

compile time error.....can not override m1() method

Now if I replace RemoteException in parent class with IOException and vice versa in child class. Then it is compiling.

Any other checked exception combinations are not working here, evenif I am using checked exception which are at same level.

Now I am confused why overriding is taking place only in one case, not in other cases??? I will realy appreciate your answer.

Steve McLeod
  • 51,737
  • 47
  • 128
  • 184
user392675
  • 69
  • 1
  • 1
  • 3

4 Answers4

4

When overriding a method that throws an Exception you can only throw the same Exception or a more specific subtype of that Exception.

RemoteException is a subtype of IOException. Therefore when the parent method throws IOException your child method can throw RemoteException.

You can also think it through logically. If a child method threw a broader Exception than the parent method, then the method might throw an Exception that doesn't match the parent.

Steve McLeod
  • 51,737
  • 47
  • 128
  • 184
2

You can throw a more specific exception in an overidden method, but not a less specific one. RemoteException is a subclass of IOException, so class1 can throw IOException and class2 RemoteException but not the other way round.

Jon Freedman
  • 9,469
  • 4
  • 39
  • 58
1

"Same level" doesn't count. In inheritance, you can always only specialize things. So class2.m1 can throw anything which inherits from the original exception but it can't widen the exception (like throwing Throwable) or throw a completely different exception (IOException doesn't inherit from RemoteException).

You could overload IOException with FileNotFoundException, for example. The reason is the catch:

 } catch( IOException e) { ... }

This works for subtypes of IOException but would break for anything else which isn't what the developer would expect.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
0

Like with return types (since Java 5) Exceptions mentioned inside the method signature are covariant.

This means you can make them more specific in classes that inherit the original method. This concept is also called narrowing of constraints because you make it more specific what the types are.

public class Foo {...}


public class SomeException extends Exception {...}


public class A{
    public Foo methodName() throws SomeException{...}
}


public class Bar extends Foo {...}


public class SomeSpecificException extends SomeException {...}


public class B extends A {
    public Bar methodName() throws SomeSpecificException {...}
}

So you can always go "down" the Inheritance hierarchy.

// Doesn't compile    
public class B extends A {
    public Object methodName() throws Exception {...}
}

Trying to widen the constraints doesn't work.

Johannes Wachter
  • 2,715
  • 17
  • 17