Why can't overriding methods throw exceptions for an overridden method?

I went through a book of SCJP 6 from Kathe sierra and came across this explanation of throwing exceptions in an overridden method. I did not understand this. Can anyone explain this to me?

The overriding method should NOT throw checked exceptions that are new or wider than those declared by the overridden method. For example, a method that throws a FileNotFoundException exception cannot override a method that throws a SQLException, Exception, or any other non-working exception if it is not a subclass of FileNotFoundException.

+92
java
May 03 '11 at 20:38
source share
14 answers

This means that if a method announces the throwing of this exception, the overriding method in the subclass can only declare this exception or its subclass. For example:

class A { public void foo() throws IOException {..} } class B extends A { @Override public void foo() throws SocketException {..} // allowed @Override public void foo() throws SQLException {..} // NOT allowed } 

SocketException extends IOException , but SQLException does not work.

This is due to polymorphism:

 A a = new B(); try { a.foo(); } catch (IOException ex) { // forced to catch this by the compiler } 

If B decided to throw a SQLException , the compiler could not get you to catch it, because you are referring to an instance of B in its superclass - A On the other hand, any subclass of IOException will be handled by sentences (catch or throws) that handle IOException

The rule that you must have in order to be able to refer to objects with your superclass is the Liskov Principle of Replacement.

Since excluded exceptions can be thrown anywhere, then they do not fall under this rule. You can add an excluded exception to the throws clause as a documentation form if you want, but the compiler does nothing.

+146
May 03 '11 at 20:41
source share

The CAN override method can raise any exception (runtime), regardless of whether the overridden method raises an exception

Example:

 class Super { public void test() { System.out.println("Super.test()"); } } class Sub extends Super { @Override public void test() throws IndexOutOfBoundsException { // Method can throw any Unchecked Exception System.out.println("Sub.test()"); } } class Sub2 extends Sub { @Override public void test() throws ArrayIndexOutOfBoundsException { // Any Unchecked Exception System.out.println("Sub2.test()"); } } class Sub3 extends Sub2 { @Override public void test() { // Any Unchecked Exception or no exception System.out.println("Sub3.test()"); } } class Sub4 extends Sub2 { @Override public void test() throws AssertionError { // Unchecked Exception IS-A RuntimeException or IS-A Error System.out.println("Sub4.test()"); } } 
+22
Nov 29 '12 at 12:52
source share

In my opinion, this is a failure in the Java syntax. Polymorphism should not limit the use of exception handling. In fact, other computer languages โ€‹โ€‹do not (C #).

In addition, the method is overridden in a more specialized subclass, so it is more complex and therefore more likely to throw new exceptions.

+14
Oct 11 '13 at 11:28
source share

To illustrate this, consider:

 public interface FileOperation { void perform(File file) throws FileNotFoundException; } public class OpenOnly implements FileOperation { void perform(File file) throws FileNotFoundException { FileReader r = new FileReader(file); } } 

Suppose you write:

 public class OpenClose implements FileOperation { void perform(File file) throws FileNotFoundException { FileReader r = new FileReader(file); r.close(); } } 

This will give you a compilation error because r.close () throws an IOException that is wider than FileNotFoundException.

To fix this, write:

 public class OpenClose implements FileOperation { void perform(File file) throws IOException { FileReader r = new FileReader(file); r.close(); } } 

You will get another compilation error because you are executing a run operation (...), but throwing an exception not included in the method interface definition.

Why is it important? Well, an interface consumer may have:

 FileOperation op = ...; try { op.perform(file); } catch (FileNotFoundException x) { log(...); } 

If an IOException was allowed to be thrown, the client code will be more correct.

Please note that you can avoid this kind of problem if you use excluded exceptions. (I do not suggest you do it or not, this is a philosophical problem)

+6
May 03 '11 at 20:47
source share

I am providing this answer here for an old question, since no answers say that the overriding method can throw anything else , which the overriding method can do:

1) throws the same exception

 public static class A { public void m1() throws IOException { System.out.println("A m1"); } } public static class B extends A { @Override public void m1() throws IOException { System.out.println("B m1"); } } 

2) throw a subclass of the overriden excluded method

 public static class A { public void m2() throws Exception { System.out.println("A m2"); } } public static class B extends A { @Override public void m2() throws IOException { System.out.println("B m2"); } } 

3) do not throw anything.

 public static class A { public void m3() throws IOException { System.out.println("A m3"); } } public static class B extends A { @Override public void m3() //throws NOTHING { System.out.println("B m3"); } } 

4) No RuntimeExceptions in the rolls are required.

The throws may or may not have RuntimeExceptions; the compiler will not complain about it. RuntimeExceptions are not checked by exceptions. Only checked exceptions should appear in the rolls if they are not caught.

+6
Feb 29 '16 at 5:44
source share

Take an interview Question. There is a method that throws a NullPointerException in the superclass. Can we override it with a method that raises a RuntimeException?

To answer this question, let us know what the Unchecked and Checked exception is.

  1. Exceptions checked must be explicitly caught or propagated as described in the "Initial Processing" section. Excluded exceptions do not have this requirement. They must not be caught or declared abandoned.

  2. Checked exceptions in Java extend the java.lang.Exception class. Excluded exceptions extend the java.lang.RuntimeException.

Public class NullPointerException extends RuntimeException

Excluded exceptions extend the java.lang.RuntimeException. Why is NullPointerException an Uncheked exception.

Take an example: Example 1:

  public class Parent { public void name() throws NullPointerException { System.out.println(" this is parent"); } } public class Child extends Parent{ public void name() throws RuntimeException{ System.out.println(" child "); } public static void main(String[] args) { Parent parent = new Child(); parent.name();// output => child } } 

The program will be successfully compiled. Example 2:

  public class Parent { public void name() throws RuntimeException { System.out.println(" this is parent"); } } public class Child extends Parent{ public void name() throws NullPointerException { System.out.println(" child "); } public static void main(String[] args) { Parent parent = new Child(); parent.name();// output => child } } 

The program will also be successfully compiled. Therefore, it is obvious that nothing happens with Unchecked exceptions. Now let's see what happens with Checked Exceptions. Example 3. When the base class and child class throw an exception

  public class Parent { public void name() throws IOException { System.out.println(" this is parent"); } } public class Child extends Parent{ public void name() throws IOException{ System.out.println(" child "); } public static void main(String[] args) { Parent parent = new Child(); try { parent.name();// output=> child }catch( Exception e) { System.out.println(e); } } } 

The program will be successfully compiled. Example 4: When a method of a child class throws an exception limited by boundaries, compared with the same method of the base class.

 import java.io.IOException; public class Parent { public void name() throws IOException { System.out.println(" this is parent"); } } public class Child extends Parent{ public void name() throws Exception{ // broader exception System.out.println(" child "); } public static void main(String[] args) { Parent parent = new Child(); try { parent.name();//output=> Compilation failure }catch( Exception e) { System.out.println(e); } } } 

The program does not compile. Therefore, we must be careful when using Checked Exceptions.

+3
Feb 07 '18 at 16:27
source share

let's say that you have a superclass A with method M1 throwin E1 and a class B derived from A with method M2 overriding M1. M2 cannot throw anything DIFFERENT or LESS SPECIALIZED than E1.

Due to polymorphism, a client using class A should be able to treat B as if it were A. Inharitance ===> Is-a (B is-a A). What if this class A code handled an E1 exception because M1 announces that it has selected this checked exception, but then a different type of exception is thrown? If M1 throws an IOException, M2 can distinguish a FileNotFoundException, as this is an IOException. Clients A can handle this without a problem. If the exception were wider, clients A would not have a chance to find out about it and, therefore, would not have a chance to catch it.

+2
May 03 '11 at 20:45
source share

Well java.lang.Exception extends java.lang.Throwable. java.io.FileNotFoundException extends java.lang.Exception. So if the throws method is java.io.FileNotFoundException, then in the override method you cannot throw anything higher than the hierarchy than FileNotFoundException, for example. you cannot throw java.lang.Exception. However, a subclass of FileNotFoundException could be used. However, you will be forced to handle a FileNotFoundException in the overriden method. Drive the code and try it!

Rules exist, so you donโ€™t lose the original throws declaration by expanding it, because polymorphism means you can call the overriden method on the superclass.

+1
May 03 '11 at 20:44
source share

The override method should NOT throw checked exceptions that are new or wider than those declared by the overridden method.

Example:

 class Super { public void throwCheckedExceptionMethod() throws IOException { FileReader r = new FileReader(new File("aFile.txt")); r.close(); } } class Sub extends Super { @Override public void throwCheckedExceptionMethod() throws FileNotFoundException { // FileNotFoundException extends IOException FileReader r = new FileReader(new File("afile.txt")); try { // close() method throws IOException (that is unhandled) r.close(); } catch (IOException e) { } } } class Sub2 extends Sub { @Override public void throwCheckedExceptionMethod() { // Overriding method can throw no exception } } 
+1
Nov 29 '12 at 13:22
source share

The override method should NOT throw checked exceptions that are new or wider than those declared by the overridden method.

It just means when you override an existing method, the exception that this overloaded method throws should be the same exception that the original method or any of its subclasses has selected .

Note that checking whether all checked exceptions are checked is performed at compile time, and not at run time. Thus, during compilation, the Java compiler checks the type of exception that the overridden method throws. Since which overridden method will be executed can only be resolved at runtime, we cannot know which exception we should catch.




Example

Say we have a class A and its subclass B A has method m1 , and class B overrides this method (lets call it m2 to avoid confusion ..). Now let's say m1 throws E1 and m2 throws E2 , which is an E1 superclass. Now write the following code fragment:

 A myAObj = new B(); myAObj.m1(); 

Note that m1 is nothing more than a call to m2 (again, the method signatures are the same in overloaded methods, so don't confuse with m1 and m2 .. they just have to distinguish in this example ... they have the same signature). But during compilation, the entire java compiler works with the reference type (class A in this case) checks the method, if it is present, and expects the programmer to process it. So, obviously, you throw or catch E1 . Now, at runtime, if the overloaded method throws E2 , which is an E1 superclass, then ... well, this is very wrong (for the same reason we cannot say B myBObj = new A() ). Therefore, Java does not allow this. Uncontrolled exceptions thrown by the overloaded method must be the same, subclasses, or nonexistent.

+1
Oct 03 '13 at 14:35
source share

To understand this, let's look at an example where we have a Mammal class that defines a readAndGet method that reads a file, performs some operation on it, and returns an instance of the Mammal class.

 class Mammal { public Mammal readAndGet() throws IOException {//read file and return Mammal object} } 

The Human class extends the Mammal class and overrides the readAndGet method readAndGet returning an instance of Human instead of an instance of Mammal .

 class Human extends Mammal { @Override public Human readAndGet() throws FileNotFoundException {//read file and return Human object} } 

To call readAndGet we need to handle an IOException because it is a checked exception, and the readAndMethod mammal readAndMethod it.

 Mammal mammal = new Human(); try { Mammal obj = mammal.readAndGet(); } catch (IOException ex) {..} 

And we know that for the compiler, mammal.readAndGet() is called from an object of the Mammal class, but at run time the JVM will allow mammal.readAndGet() method to be called from the Human class because the mammal holding new Human() .

The readAndMethod method from Mammal readAndMethod IOException and, since it is a proven exception compiler, it will force us to catch it whenever we call readAndGet for a mammal

Now suppose that readAndGet in Human readAndGet any other checked exception, such as Exception, and we know that readAndGet will be called from the Human instance because the mammal contains new Human() .

Since for the compiler the method is called from Mammal , therefore, the compiler will force us to handle only an IOException but at runtime we know that the method will Exception which is not being processed, and our code will abort if the method throws an exception.

This is why this is prevented at the compiler level, and we are not allowed to throw any new or wider checked exceptions, because in the end they will not be processed by the JVM.

There are other rules that we must follow when redefining methods, and you can read more about why we should follow redefinition rules to find out the reasons.

+1
Dec 22 '17 at 8:54
source share

What explanation do we attribute below

 class BaseClass { public void print() { System.out.println("In Parent Class , Print Method"); } public static void display() { System.out.println("In Parent Class, Display Method"); } } class DerivedClass extends BaseClass { public void print() throws Exception { System.out.println("In Derived Class, Print Method"); } public static void display() { System.out.println("In Derived Class, Display Method"); } } 

The DerivedClass.java class throws a compile-time exception, when the print method throws an exception, the print () method of the base class does not throw any exceptions

I can explain this with the fact that Exception is narrower than RuntimeException, it can be either No Exception (Runtime error), RuntimeException and their child exceptions

0
Jan 07 '13 at 14:40
source share

The subclass override method can throw only a few checked exceptions that are subclasses of the excluded superclass check method, but cannot throw multiple checked exceptions that are not related to the superclass excluded method. Exception thrown

0
Oct. 17 '18 at 6:44
source share

Java gives you the ability to limit exceptions in the parent class, since it assumes that the client will limit the detected infection. IMHO you should essentially never use this "feature" because your customers may need flexibility along the way.

Java is an old language that is poorly designed. Modern languages โ€‹โ€‹do not have such restrictions. The easiest way to avoid this drawback is to make a throw Exception base class. Clients may throw more specific exceptions, but make your base classes very broad.

0
Dec 04 '18 at 21:42
source share



All Articles