Java Language The 'throws' clause in a method declaration


Example

Java's checked exception mechanism requires the programmer to declare that certain methods could throw specifed checked exceptions. This is done using the throws clause. For example:

public class OddNumberException extends Exception { // a checked exception
}

public void checkEven(int number) throws OddNumberException {
    if (number % 2 != 0) {
        throw new OddNumberException();
    }
}

The throws OddNumberException declares that a call to checkEven could throw an exception that is of type OddNumberException.

A throws clause can declare a list of types, and can include unchecked exceptions as well as checked exceptions.

public void checkEven(Double number) 
        throws OddNumberException, ArithmeticException {
    if (!Double.isFinite(number)) {
        throw new ArithmeticException("INF or NaN");
    } else if (number % 2 != 0) {
        throw new OddNumberException();
    }
}

What is the point of declaring unchecked exceptions as thrown?

The throws clause in a method declaration serves two purposes:

  1. It tells the compiler which exceptions are thrown so that the compiler can report uncaught (checked) exceptions as errors.

  2. It tells a programmer who is writing code that calls the method what exceptions to expect. For this purpose, it often makes to senses to include unchecked exceptions in a throws list.

Note: that the throws list is also used by the javadoc tool when generating API documentation, and by a typical IDE's "hover text" method tips.

Throws and method overriding

The throws clause forms part of a method's signature for the purpose of method overriding. An override method can be declared with the same set of checked exceptions as thrown by the overridden method, or with a subset. However the override method cannot add extra checked exceptions. For example:

@Override
public void checkEven(int number) throws NullPointerException // OK—NullPointerException is an unchecked exception
    ...

@Override
public void checkEven(Double number) throws OddNumberException // OK—identical to the superclass
    ...

class PrimeNumberException extends OddNumberException {}
class NonEvenNumberException extends OddNumberException {}

@Override
public void checkEven(int number) throws PrimeNumberException, NonEvenNumberException // OK—these are both subclasses

@Override
public void checkEven(Double number) throws IOExcepion         // ERROR

The reason for this rule is that if an overriden method can throw a checked exception that the overridden method could not throw, that would break type substitutability.