I was going through SCJP 6 book by Kathe sierra and came across this explanations of throwing exceptions in overridden method. I quite didn't get it. Can any one explain it to me ?
The overriding method must NOT throw checked exceptions that are new or broader than those declared by the overridden method. For example, a method that declares a FileNotFoundException cannot be overridden by a method that declares a SQLException, Exception, or any other non-runtime exception unless it's a subclass of FileNotFoundException.
I provide this answer here to the old question since no answers tell the fact that the overriding method can throw nothing here's again what the overriding method can throw:
1) throw the same exception
2) throw subclass of the overriden method's thrown exception
3) throw nothing.
4) Having RuntimeExceptions in throws is not required.
There can be RuntimeExceptions in throws or not, compiler won't complain about it. RuntimeExceptions are not checked exceptions. Only checked exceptions are required to appear in throws if not catched.
Let us take an interview Question. There is a method that throws NullPointerException in the superclass. Can we override it with a method that throws RuntimeException?
To answer this question, let us know what is an Unchecked and Checked exception.
Checked exceptions must be explicitly caught or propagated as described in Basic try-catch-finally Exception Handling. Unchecked exceptions do not have this requirement. They don't have to be caught or declared thrown.
Checked exceptions in Java extend the java.lang.Exception class. Unchecked exceptions extend the java.lang.RuntimeException.
public class NullPointerException extends RuntimeException
Unchecked exceptions extend the java.lang.RuntimeException. Thst's why NullPointerException is an Uncheked exception.
Let's take an example: Example 1 :
The program will compile successfully. Example 2:
The program will also compile successfully. Therefore it is evident, that nothing happens in case of Unchecked exceptions. Now, let's take a look what happens in case of Checked exceptions. Example 3: When base class and child class both throws a checked exception
The program will compile successfully. Example 4: When child class method is throwing border checked exception compared to the same method of base class.
The program will fail to compile. So, we have to be careful when we are using Checked exceptions.
What explanation do we attribute to the below
Class DerivedClass.java throws a compile time exception when the print method throws a Exception , print () method of baseclass does not throw any exception
I am able to attribute this to the fact that Exception is narrower than RuntimeException , it can be either No Exception (Runtime error ), RuntimeException and their child exceptions
say you have super class A with method M1 throwin E1 and class B deriving from A with method M2 overriding M1. M2 can not throw anything DIFFERENT or LESS SPECIALIZED than E1.
Because of polymorphism, the 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 code dealing with class A was handling exception E1, as M1 declares it throws this checked exception, but then different type of exception was thrown? If M1 was throwing IOException M2 could well throw FileNotFoundException, as it is-a IOException. Clients of A could handle this without a problem. If the exception thrown was wider, clients of A would not have a chance of knowing about this and therefore would not have a chance to catch it.
In my opinion, it is a fail in the Java syntax design. Polymorphism shouldn't limit the usage of exception handling. In fact, other computer languages don't do it (C#).
Moreover, a method is overriden in a more specialiced subclass so that it is more complex and, for this reason, more probable to throwing new exceptions.
It means that if a method declares to throw a given exception, the overriding method in a subclass can only declare to throw that exception or its subclass. For example:
SocketException extends IOException
, butSQLException
does not.This is because of polymorphism:
If
B
had decided to throwSQLException
, then the compiler could not force you to catch it, because you are referring to the instance ofB
by its superclass -A
. On the other hand, any subclass ofIOException
will be handled by clauses (catch or throws) that handleIOException
The rule that you need to be able to refer to objects by their superclass is the Liskov Substitution Principle.
Since unchecked exceptions can be thrown anywhere then they are not subject to this rule. You can add an unchecked exception to the throws clause as a form of documentation if you want, but the compiler doesn't enforce anything about it.