In Java, exception handling in inheritance follows specific rules to ensure that overridden methods maintain compatibility with the base class in terms of the exceptions they throw. When a subclass overrides a method from its superclass, it must adhere to certain constraints related to checked exceptions.
Core Concepts
1. Checked Exceptions
- A subclass can only throw the same or a subclass of the checked exception declared in the superclass method.
- The subclass cannot throw broader (new or additional) checked exceptions.
2. Unchecked Exceptions
- A subclass method can throw unchecked exceptions (like
NullPointerException,ArithmeticException) without restriction, regardless of the superclass method.
3. No Exception in Superclass
- If the superclass method does not declare any checked exception, then the subclass method cannot declare any new checked exception.
- Unchecked exceptions are still allowed.
Example Program Demonstrating Exception Handling in Inheritance
Simulate a Software Engineering designation hierarchy where each role overrides a method performDuties() that may throw exceptions (e.g., project delivery errors). Show how exception handling rules in inheritance apply.
// Base class
class Engineer {
public void performDuties() throws java.io.IOException {
System.out.println("Engineer is writing code...");
throw new java.io.IOException("Code build failed!");
}
}
// Subclass throwing same exception
class SeniorEngineer extends Engineer {
@Override
public void performDuties() throws java.io.FileNotFoundException {
System.out.println("Senior Engineer is reviewing code...");
throw new java.io.FileNotFoundException("Review document missing!");
}
}
// Subclass throwing unchecked exception
class TeamLead extends Engineer {
@Override
public void performDuties() throws RuntimeException {
System.out.println("Team Lead is managing the project...");
throw new RuntimeException("Project deadline missed!");
}
}
// Subclass with illegal checked exception (Uncomment to see error)
/*
class Manager extends Engineer {
@Override
public void performDuties() throws Exception { // Compile-time error
System.out.println("Manager is allocating resources...");
}
}
*/
public class SoftwareTeam {
public static void main(String[] args) {
Engineer engineer;
engineer = new SeniorEngineer();
try {
engineer.performDuties();
} catch (java.io.IOException e) {
System.out.println("Caught IOException: " + e.getMessage());
}
engineer = new TeamLead();
try {
engineer.performDuties();
} catch (RuntimeException e) {
System.out.println("Caught RuntimeException: " + e.getMessage());
}
}
}
/*
Senior Engineer is reviewing code...
Caught IOException: Review document missing!
Team Lead is managing the project...
Caught RuntimeException: Project deadline missed!
*/Important Rules
| Rule | Explanation |
|---|---|
| ✅ Subclass method can throw same or narrower checked exception | e.g., FileNotFoundException instead of IOException |
| ❌ Subclass cannot throw broader/new checked exceptions | Leads to compile-time error |
| ✅ Subclass method can throw unchecked exceptions | No restriction |
| ❌ If superclass method does not declare checked exceptions, subclass cannot add them | Violates method signature contract |
Exception handling in inheritance ensures that polymorphism works seamlessly and predictably. It enforces that clients depending on a superclass method are not surprised by additional checked exceptions introduced in subclass methods. Following these rules leads to more robust and maintainable object-oriented programs.
