Skip to main content

Using Throws and Throw Statements in Java

Posted by manning_pubs on June 13, 2013 at 1:17 AM PDT






Using Throws and Throw Statements in Java

By Mala Gupta, author of OCP Java SE 7 Programmer II Certification Guide

In this article, based on chapter 1 of OCP Java SE 7 Programmer II Certification Guide, author Mala Gupta explains how to define methods that throw exceptions, the different combinations of defining overriding methods, and when the overridden or overriding methods throw checked exceptions. Save 42% on OCP Java SE 7 Programmer II Certification Guide with Promotional Code ocplaujn, only at manning.com.

Imagine you have been assigned a task of finding a specific book, and then reading and explaining its contents to a class of students. The required sequence may look like:

  • Get the specified book
  • Read aloud its contents
  • Explain the contents to a class of students.

But what happens if you can't find the specified book? You can't proceed with the rest of the action without it so you need to report back to the person who assigned the task to you. This unexpected event (missing book) prevents you from completing your task. By reporting it back, you want the originator of this request to take corrective or alternate steps.

Let's code the above task as method teachClass, as shown in figure 1 and use it to compare the throw and throws statement. This example code is for demonstration purpose only because it uses methods locateBook, readBook, and explainContents, which aren't defined.

Figure 1 Comparing throws and throw statement

Code in figure 1 is simple to follow. On execution of code throw new BookNotFoundException, execution of teachClass() halts. The JVM creates an instance of BookNotFoundException and sends it to off to the caller of teachClass() so that alternate arrangements can be made.

The throw statement is used to throw an instance of exception—BookNotFoundException. The throws statement is used in the signature of method teachClass to signal that it can throw exception BookNotFoundException.

Why does a method choose to throw an exception as opposed to handling it itself? It's a contract between the calling method and the called method. Referring back to the method teachClass, as shown in figure 1, the caller of teachClass would like to be informed if teachClass is unable to find the specified book. The method teachClass doesn't handle BookNotFoundException itself because its responsibilities don't include how to work around a missing book.

Creating a method that throws a checked exception

Let's create a simple method, which doesn't handle the checked exception thrown by it, by using the keywords throw and throws. Class DemoThrowsException defines method readFile, which includes a throws statement in its method signature. The actual throwing of an exception is accomplished by the throw statement:

import java.io.FileNotFoundException;
class DemoThrowsException {
    public void readFile(String file) throws FileNotFoundException {     #A
        boolean found = findFile(file);                        
        if (!found)
            throw new FileNotFoundException("Missing file");    #B
        else {
            //code to read file
        }
    }
    boolean findFile(String file) {
        //code to return true if file can be located
    }
}

#A The throws statement indicates that this method can throw FileNotFoundException
#B If file can't be found, code creates and throws an object of FileNotFoundException by using the throw statement

A method can include names of multiple, comma separated names in its throws statement. It isn't obligatory to include names of Runtime exceptions or errors in the throws statement. A method can still throw instances of Runtime exceptions or errors, without including them in its throws statement.

Using a method that throws a checked exception

When you use a method that throws a checked exception, you can:

  • Enclose the code within a try block and catch the thrown exception.
  • Declare the exception to be rethrown in the method's signature.
  • Implement both the above together.

In the following example, method useReadFile encloses the usage of the method readFile within a try-catch block. Method readFile throws FileNotFoundException (a checked exception):

class DemoThrowsException {
    public void readFile(String file) throws FileNotFoundException {
        //..code
    }
    void useReadFile (String name) {               #A
        try {                                      #B
            readFile(name);                        #B
        }                                          #B
        catch (FileNotFoundException e) {         
            //code                                
        }                                         
    }
}

#A Method useReadFile uses method readFile that throws FileNotFileException
#B Call to method readFile should be enclosed in a try block because it throws checked exception FileNotFoundException

In the modified definition of method useReadFile, you can make the method useReadFile throw the exception thrown by the method readFile:

class DemoThrowsException {
    public void readFile(String file) throws FileNotFoundException {
        //..code
    }
    void useReadFile(String name) throws FileNotFoundException{  #A
        readFile(name);                                          #B
    }
}

#A useReadFile() declares that it throws exception FileNotFoundException
#B Usage of method readFile need not be enclosed in a try block

The compiler doesn't complain if you mix the above approaches—method useReadFile can handle FileNotFoundException itself and still declare it to be thrown (highlighted using boldface):

import java.io.*;
class DemoThrowsException {
    public void readFile(String file) throws FileNotFoundException {
        //..code
    }
    void useReadFile (String name) throws FileNotFoundException{ #A

        try {                                                    #B
            readFile(name);                                      #B
        }                                                        #B
        catch (FileNotFoundException e) {
            //code
        }
    }
}

#A useReadFile() declares that it throws exception FileNotFoundException

#B Usage of method readFile is enclosed in a try block

So what happens when FileNotFoundException is thrown by method readFile()? Will its catch block handle FileNotFoundException, or will it throw it to its calling method?

Points to note while using throws and throw statement

Apart from knowing the need of throwing exceptions, using their syntax, you should be aware about a couple of rules to throw exceptions using throw and throws statement, as discussed in this section.

It isn't obligatory to include runtime exceptions or errors in throws statement

Let's modify the above example so that method readFile throws a runtime exception—NullPointerException, when a null value is passed to it (changes in boldface):

import java.io.FileNotFoundException;
class DemoThrowsException {
    public void readFile(String file) throws FileNotFoundException {     #A
        if (file == null)
            throw new NullPointerException();                   #B
        boolean found = findFile(file);                        
        if (!found)
            throw new FileNotFoundException("Missing file");    #C
        else {
            //code to read file
        }
    }
    boolean findFile(String file) {
        //code to return true if file can be located
    }
}

#A The throws statement indicates that this method can throw FileNotFoundException
#B Code throws NullPointerException, but it is not included in throws statement
#C If file can't be found, code creates and throws an object of FileNotFoundException

The exam might trick you by including the names of runtime exceptions and errors in one method and leaving out in another. You can include the name of a runtime exception in the throws statement. Assuming that the rest of the code remains the same, the following method signature is correct:

public void readFile(String file) 
                  throws NullPointerException, FileNotFoundException {  #A
    //rest of the code remains same
}

#A Though not required, inclusion of runtime exceptions in the throws statement is valid

EXAM TIP It isn't obligatory to include the name of the runtime exceptions or errors in the throws statement. A method can throw a runtime exception or error irrespective of whether their names are included in method's throws statement.

A method can throw a subclass of exception mentioned in its throws statement not its superclass

Because class IOException is a superclass of class FileNotFoundException, method readFile, can't throw an object of class IOException:

class DemoThrowsException {
    public void readFile(String file) throws FileNotFoundException {    #A
        boolean found = findFile(file);                        
        if (!found)
            throw new IOException("Missing file");                      #B
        else {
            //code to read file
        }
    }
    boolean findFile(String file) {
        //code to return true if file can be located
    }
}

#A The throws statement includes FileNotFoundException
#B Won't compile—can't throw an object of superclass of checked exception mentioned in throws statement

Let's modify the definition of method readFile by making it throw IOException. Because IOException is a super class of class FileNotFoundException, readFile() can throw an object of FileNotFoundException (changes in boldface):

class DemoThrowsException {
    public void readFile(String file) throws IOException {    #A
        boolean found = findFile(file);                        
        if (!found)
            throw new FileNotFoundException("Missing file");  #B
        else {
            //code to read file
        }
    }
    boolean findFile(String file) {
        //code to return true if file can be located
    }
}

#A The throws statement includes IOException

#B Will compile—can throw an object of derived class of checked exception mentioned in throws statement

Note that this rule doesn't apply to the errors and runtime exceptions because the throws statement doesn't need to specify the names of the errors and runtime exceptions.

A method can handle the exception and still declare it to be thrown

This is usually done by methods whose exception handlers might throw the same exception. The method useReadFile() handles the exception FileNotFoundException and also declares it to be rethrown:

class DemoThrowsException {
    public void readFile(String file) throws FileNotFoundException {
        //..code
    }
    void useReadFile(String name) throws FileNotFoundException {   #A
        try {                                     
            readFile(name);                       
        }                                         
        catch (FileNotFoundException e) {                          #B
            //code

            throw new FileNotFoundException();                     #C           
        }                                         
    }
}

#A useReadFile() throws FileNotFoundException
#B This code is valid—useReadFile() handles FileNotFoundException from method readFile
#C This exception instance will be handed over to method that calls method useReadFile

A method that declares a checked exception to be thrown might not actually throw it

Method readFile() includes the name of checked exception—FileNotFoundException—in its throws statement, but doesn't throw it:

import java.io.FileNotFoundException;
class DemoThrowsException {
    public void readFile(String file) throws FileNotFoundException {   #A
        System.out.println("readFile:" + file);                        #A
    }                                                                  #A
}

#A Compiles successfully even if readFile doesn't throw an instance of FileNotFoundExcception

But do you think you can call readFile() as a method that doesn't throw an exception, that is, without enclosing it within a try-catch block or rethrowing the exception?

Rethrowing exceptions with more inclusive type checking

Starting with Java version 7, the type of the variable that you use to rethrow a thrown exception can be more generic in the catch block:

class GenericVariableTypeToRethrowException {
    public static void main(String args[])
                          throws IOException, SQLException {    #A
        String source = "DBMS";
        try {
            if (source.equals("DBMS")) throw new SQLException();
            else throw new IOException();
        }
        catch (Exception e) {            #B
            throw e;                    #C
        }
    }
}

#A Method declares to throw exceptions IOException and SQLException
#B Type of variable e in catch block is Exception—more generic than IOException and SQLException
#C Catch block rethrows the caught exception

In the try block, the code throws either an object of SQLException or IOException, conditionally. With Java 7, the compiler can determine that the exception object received by the catch block is either of these types and so it's okay to rethrow it, even if the type of the exception variable in the exception handler is Exception—a super class of SQLException and IOException. This, however, wasn't allowed in Java versions prior to 7.

Do you think the code will compile successfully if instead of rethrowing the exception in the catch block, you create a new object of class Exception and throw it? No, it won't. Because it would be a direct violation of the contract between the declaration of exceptions that method main states to be throwing and what it actually throws.

EXAM TIP With Java 7, you can rethrow exceptions with more inclusive type checking.

Summary

Exception handling is covered both in the OCA Java SE 7 Programmer I exam (1Z0-803) and OCP Java SE 7 Programmer II exam (1Z0-804). In this article, I covered a topics that are specific to the latter exam: the throw and throws statements.

You can throw your own custom exceptions from methods by using the throw and throws statement, in the same way you work with the exception classes from the Java API.


Here are some other Manning titles you might be interested in:

Unit Testing in Java

Unit Testing in Java
Lasse Koskela

Making Java Groovy

Making Java Groovy
Kenneth Kousen

Play for Java

Play for Java
Nicolas Leroux and Sietse de Kaper


Related Topics >>