Thursday, 17 February 2011

Exceptions and Overriding

When you extend a class and override a method, the Java compiler insists that all exception classes thrown by your overridden method must be the same as, or subclasses of, the exception classes thrown by the original method in the base class. The code below demonstrates a base class being overridden by various subclasses.


  /**
   * Base class for the example
   */
 
public class BaseClass {
   
   
/**
     * Example method - throws IOException
     *
@throws IOException
     */
   
public void method() throws IOException {
   
    }
  }
 
 
/**
   * Example of a legal class
   */
 
public class LegalOne extends BaseClass {
   
   
/**
     * This is okay as it throws the same method as the base class
     *
@throws IOException
     */
   
public void method() throws IOException {
   
    }
  }

 
/**
   * Example of a legal class
   */
 
public class LegalTwo extends BaseClass{
   
   
/**
     * This is okay as it doesn't throw an exception
     */
   
public void method() {
   
    }
  }

 
/**
   * Example of a legal class
   */
 
public class LegalThree extends BaseClass {
   
   
/**
     * This is okay as it throws exceptions that as subclasses of IOException
     *
@throws FileNotFoundException
     *
@throws MalformedURLException
     */
   
public void method() throws FileNotFoundException, MalformedURLException {
   
    }
  }

 
/**
   * Example of an illegal class
   */
 
public class IllegalOne extends BaseClass {
   
   
/**
     * This is illegal as the exception it throws is not related to IOException
     *
@throws IOException
     */
   
public void method() throws IllegalAccessException {
   
    }
  }


 
/**
   * Example of an illegal class
   */
 
public class IllegalTwo extends BaseClass {
   
   
/**
     * This is illegal as it throws an exception which is a base class of IOException
     *
@throws IOException
     */
   
public void method() throws Exception {
   
    }
  }

The upshot of this that you need to be careful when applying checked exceptions to classes that you know will be overridden and it’s really an indication that your class hierarchy is going wrong when the overridden method doesn’t throw the exception from the base class. This is one reason that you should really consider using RuntimeExceptions over checked exceptions when highlighting errors and, as a rule of thumb, reserve checked exceptions for business exceptions... but more on that later.