Exception Handling with Method Overriding in Java
In this tutorial, we will understand about rules for exception handling, while overriding method in Java with the help of various example programs.
When a superclass method (overridden method) declares that it can throw an exception, then the subclass method (overriding method) must also declare that it can throw the same kind of exception or a subtype of that exception.
To handle the exception while you overriding a method in Java, you will have to follow three important rules. They are as follows:
1. If an overridden method does not throw an exception using throws clause, then
- The overriding method can not throw any checked or compile-time exception.
- The overriding method can throw any unchecked or runtime exception.
2. If an overridden method throws an unchecked or runtime exception, then
- The overriding method can throw any unchecked or runtime exception.
- The overriding method can throw the same exception, which is thrown by the overridden method.
- The overriding method can ignore the method level exception.
3. If the superclass method throws a checked or compile-time exception, then
- Subclass method can throw an exception, which is a subclass of the superclass method’s exception.
- Subclass method cannot throw the exception, which is a superclass of the superclass method’s exception.
- Subclass method can throw any unchecked or runtime exception.
Look at the below figure to understand better.
Exceptional Handling with Method Overriding Examples
Let’s take some example programs based on the rules of exception handling while overriding a method in Java.
Example 1:
package overriding;
public class Parent
{
// Overridden method is not throwing an exception.
void msg()
{
System.out.println("msg-Parent");
}
}
import java.io.IOException;
public class Child extends Parent
{
// Here, the overriding method is throwing a checked exception. Therefore, it will generate a compile-time error.
void msg() throws IOException
{
System.out.println("msg-Child");
}
public static void main(String[] args) throws IOException
{
Parent p = new Child();
p.msg();
Child c = new Child();
c.msg();
}
}
Output: Unresolved compilation problem: Exception IOException is not compatible with throws clause in Parent.msg()
In this example, we have defined a class Parent which contains a msg() method. This method does not accepts any arguments. Inside the msg() method of the Parent class, a message “msg-Parent” is printed using System.out.println().
Then, we have defined a class Child that extends the Parent class, meaning it inherits the properties and methods of the Parent class. The Child class also defines a msg() method, which is an overridden version of the msg() method from the parent class.
The msg() method in the Child class will throw a checked exception named IOException. A checked exception must be either caught using a try-catch block or declared to be thrown.
Inside the main() method, we have created two objects.
(a) Parent p = new Child();: Here, a Parent reference variable named p refers to an object of the Child class. This demonstrates polymorphism, where a subclass object is assigned to a superclass reference.
(b) Child c = new Child();: Here, a Child reference variable named c refers to another object of the Child class.
We have called the msg() method on both objects using the respective reference variables (p.msg() and c.msg()).
Since the msg() method of class Parent is not throwing any exception, while the overriding method of class Child is throwing a checked exception named IOException.
This violates the rule of method overriding, which states that if an overridden method does not throw an exception using throws clause, the overriding method can not throw any checked or compile-time exception. However, the overriding method can throw any unchecked or runtime exception. Therefore, the compiler will generate a compile-time error.
In the above example program, if the overriding method throws an unchecked exception, there will be no compile-time error. Look at the program code.
Example 2:
package overriding;
public class Parent
{
// Overridden method is not throwing an exception.
void msg()
{
System.out.println(“msg-Parent”);
}
}
import java.io.IOException;
public class Child extends Parent
{
void msg() throws ArithmeticException // No compile-time error because the overriding method is throwing an unchecked exception.
{
System.out.println(“msg-Child”);
}
public static void main(String[] args) throws IOException
{
Parent p = new Child();
p.msg();
Child c = new Child();
c.msg();
}
}
Output: msg-Child msg-Child
Program code 3:
package overriding;
public class Parent
{
// Overridden method is throwing an unchecked exception.
void msg() throws ArithmeticException
{
System.out.println("msg-Parent");
}
}
public class Child extends Parent
{
void msg() throws ClassCastException // No compile-time error because the overriding method is throwing an unchecked exception.
{
System.out.println("msg-Child");
}
public static void main(String[] args)
{
Parent p = new Child();
p.msg();
Child c = new Child();
c.msg();
}
}
Output: msg-Child msg-Child
Question:
What will be the error in the following program? Assumption X is superclass, and Y is subclass.
1. In superclass
public void m1() throws IOException
{
System.out.println("Hello");
}
In subclass
public void m1() throws Exception
{
System.out.println("Hi");
}
Answer:
Compile-time error because the overriding method is throwing an exception, which is the superclass of the superclass method’ exception. i.e., Exception is the superclass of IOExecption.
2. In superclass
public void m1() throws Throwable
{
System.out.println("Parent");
}
In subclass
public void m1() throws Exception
{
System.out.println("Child");
}
Answer:
No compile-time error because Throwable is the superclass of all exceptions.
3. In base class
public void m1() throws Exception
{
System.out.println("Base");
}
In derived class
void m1() throws InterrurptedException
{
System.out.println("Child");
}
Answer:
Compile-time error because you cannot reduce the visibility of inherited method from Parent. Access modifiers must be bigger or same.
4. In base class
protected void m1() throws Exception
{
System.out.println("Base");
}
In derived class
public void m1() throws Exception
{
System.out.println("Child");
}
Answer: No error.
5. In superclass
protected void m1(char c) throws Throwable
{
System.out.println("Parent");
}
In subclass
void m1(char c)
{
System.out.println("Child");
}
Answer:
Error because we cannot reduce the visibility while overriding method.
In this tutorial, we have explained three important rules of exception handling with method overriding in Java with the help of various examples. Hope that you will have understood the basic rules and practiced all example programs. In the next, we will understand the basic difference between overloading and overriding in Java.