Overriding methods and exceptions

In Java, overriding allows a subclass to provide a specific implementation of a method already defined in its superclass. However, when exceptions are involved, Java enforces specific rules to ensure that exception handling remains consistent and safe across inheritance hierarchies.

Rules for Exceptions in Overriding Methods

Rule Description
Allowed The overriding method can throw fewer or more specific (subclass) checked exceptions.
Not Allowed The overriding method cannot throw new or broader checked exceptions than the overridden method.
Unchecked Exceptions There are no restrictions on throwing unchecked (runtime) exceptions in the overriding method.

Simple Program Example: Software Engineer Hierarchy

This example demonstrates how exceptions behave during method overriding using a Software Engineer designation scenario.

// Base class
class SoftwareEngineer {
    public void doWork() throws java.io.IOException {
        System.out.println("Software Engineer is coding...");
        throw new java.io.IOException("Build failed.");
    }
}

// Subclass overriding with a more specific exception
class SeniorEngineer extends SoftwareEngineer {
    @Override
    public void doWork() throws java.io.FileNotFoundException {
        System.out.println("Senior Engineer is reviewing code...");
        throw new java.io.FileNotFoundException("Review file missing.");
    }
}

// Subclass overriding without throwing any exception
class Intern extends SoftwareEngineer {
    @Override
    public void doWork() {
        System.out.println("Intern is learning...");
        // No exception thrown
    }
}

// Subclass overriding with unchecked exception
class TechLead extends SoftwareEngineer {
    @Override
    public void doWork() throws RuntimeException {
        System.out.println("Tech Lead is managing tasks...");
        throw new RuntimeException("Task mismanagement error.");
    }
}

// Illegal override (Uncommenting this will cause compile-time error)
/*
class Architect extends SoftwareEngineer {
    @Override
    public void doWork() throws Exception { // ❌ Compile-time error
        System.out.println("Architect is designing...");
    }
}
*/

public class EngineerDemo {
    public static void main(String[] args) {
        SoftwareEngineer engineer;

        // Senior Engineer
        engineer = new SeniorEngineer();
        try {
            engineer.doWork();
        } catch (java.io.IOException e) {
            System.out.println("Caught: " + e.getMessage());
        }

        // Intern
        engineer = new Intern();
        try {
            engineer.doWork();
        } catch (java.io.IOException e) {
            System.out.println("Caught: " + e.getMessage());
        }

        // Tech Lead
        engineer = new TechLead();
        try {
            engineer.doWork();
        } catch (RuntimeException e) {
            System.out.println("Caught RuntimeException: " + e.getMessage());
        }
    }
}
/*
Senior Engineer is reviewing code...
Caught: Review file missing.
Intern is learning...
Tech Lead is managing tasks...
Caught RuntimeException: Task mismanagement error.
*/

When overriding methods, Java ensures that exception handling stays safe and predictable. Subclasses may:

  • Not declare broader checked exceptions
  • Declare narrower (subclass) checked exceptions
  • Declare or skip unchecked exceptions freely

This approach maintains robust polymorphism and API integrity in real-world applications like employee roles and responsibilities.

Scroll to Top