Try-Catch

Try-Catch


This article describes how to use try-catch and finally block in Java.

The try-catch statement is used to catch exceptions. The checked and unchecked exceptions can be caught both. 

A try block is the place where a checked or an unchecked exception can be thrown. A catch block handles an exception. It defines the exception's type and a reference to it.

1. Simple Try Catch Block

Rules for writing try-catch:

  • Only one try block is allowed.
  • More than one catch block can be written.
  • The catch blocks should immediately follow the try block.
  • The catch blocks should all follow each other, without any other statements or blocks in between them.
  • It is illegal to use a try block without either a catch block or a finally block.
  • A finally block should immediately follow the last catch block (or it must immediately follow the try block if there is no catch).

Example 1.1. Catching an unchecked Exception

Let's look at the simple example where unchecked exception is caught. In the line 4 StringIndexOutOfBoundsException is thrown and the execution is transferred to the line 6. So the line 5 is never executed in this example.

1. try {
2.     String str = "Hello Java world!!!";
3.     System.out.println(str.substring(0, 5));
4.     System.out.println(str.substring(10, 20));
5.     System.out.println("The end of try block");
6. } catch (StringIndexOutOfBoundsException e) {
7.     System.out.println("In the catch block");
8. }
9. System.out.println("Done");

The output is:

Hello
In the catch block
Done

Example 1.2. Catching multiple unchecked Exceptions

Let's rewrite the previous example to be executed without throwing exceptions. In this case all lines of the try block are run and the execution is transferred to the line 11. Additionally it is added one more catch block:

1.  try {
2.      String str = "Hello Java world!!!";
3.      System.out.println(str.substring(0, 5));
4.      System.out.println(str.substring(11, 16));
5.      System.out.println("The end of try block");
6.  } catch (StringIndexOutOfBoundsException e) {
7.      System.out.println("In the StringIndexOutOfBoundsException catch block");
8.  } catch (ArrayIndexOutOfBoundsException e) {
9.      System.out.println("In the ArrayIndexOutOfBoundsException catch block");
10. }
11. System.out.println("Done");

The output is:

Hello
world
The end of try block
Done

2. Using Finally

A finally block is optional. It contains the code that is always executed after the try block, whether an exception was thrown or not. The finally block won't be executed only if it is called System.exit(). In this case the program will terminate abnormally without executing the finally block. 

  • If the try block executes with no exceptions, the finally block is executed immediately after the try block completes.
  • If there was an exception thrown, the finally block executes immediately after the proper catch block completes.
  • If there is a return statement in the try block, the finally block executes right after the return statement is encountered, and before the return executes.
  • If an exception is re-thrown inside the catch block, a finally block will be executed.

If the finally block is present, the catch block is optional. You can have both or either a catch block or a finally block. 

Example 2.1. Using Finally Block

The example demonstrates how to use try block with finally. The catch block is absent: 

try {
    System.out.println("In the try block");
} finally {
    System.out.println("In the finally block");
}
System.out.println("Done");

The output is:

In the try block
In the finally block
Done

Example 2.2. Using Try-Catch Block with Finally

Let's rewrite the Example 1.1 adding finally block:

try {
   String str = "Hello Java world!!!";
   System.out.println(str.substring(0, 5));
   System.out.println(str.substring(10, 20));
   System.out.println("The end of try block");
} catch (StringIndexOutOfBoundsException e) {
   System.out.println("In the catch block");
} finally {
   System.out.println("In the finally block");
}
System.out.println("Done");

The output is:

Hello
In the catch block
In the finally block
Done

3. Exceptions Handling

The catch block will catch not only exceptions of the specified class but it's subclasses as well. 

For example, class IndexOutOfBoundsException has two subclasses: ArrayIndexOutOfBoundsException and StringIndexOutOfBoundsException. We can rewrite the Example 1.2 using one catch block with IndexOutOfBoundsException:

Example 3.1. Handle multiple Exceptions by one Catch Block

If a code in the try block throws ArrayIndexOutOfBoundsException or StringIndexOutOfBoundsException, the exception will be handled.

try {
   String str = "Hello Java world!!!";
   System.out.println(str.substring(0, 5));
   System.out.println(str.substring(11, 16));
   System.out.println("The end of try block");
} catch (IndexOutOfBoundsException e) {
   System.out.println("In the IndexOutOfBoundsException catch block");
}
System.out.println("Done");

If an exception can be caught in several catch blocks, the exception will be caught by the first defined catch block.

Moreover, the hierarchy of the classes should be payed attention to - a catch block with subclass should be defined before a catch block with superclass.

Example 3.2. Handle multiple Subclasses Exceptions 

The code in the example has two catch blocks for Exception and IOException, which is the subclass of Exception. If the IOException is thrown, only first catch block will be executed. 

try {
    //some code
    if(...){
       throw new IOException();
    }
    //some code
} catch (IOException e) {
    System.out.println("In the IOException catch block");
} catch (Exception e) {
    System.out.println("In the Exception catch block");
}

Some previous examples define catch blocks for unchecked exception, which, in fact, cannot be thrown in try block. But it is illegal to define a catch block for a checked exception that isn't thrown by the code in the try block.

Example 3.3. Illegal Definition of the Catch Block for a checked Exception

This example won't compile because try block doesn't contain code to throw checked IOException:

try {
   System.out.println("In the try block");
} catch (IOException e) {
   System.out.println("In the IOException catch block");
}

4. Try-with-Resources in Java 7

The try-with-resources block is available since Java 7. It gives the possibility to declare one or more resources in the try block so they can be closed without doing it explicitly in a finally block.

  • We can use any object that implements java.lang.AutoCloseable as a resource.
  • Resources declared inside a try-with-resources cannot be used outside this block (they're out of scope and they're closed after the try block ends).
  • If the try block also throws an exception, the exception from the try block "wins" and the exceptions from the close() method are "suppressed".

Example 4.1. Using AutoCloseable Resource in the Try-with-Resources Statement

The BufferedReader instance is declared in a try-with-resource statement. It will be closed regardless of whether the try statement completes normally or not.

public String readLine(String fileName) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(fileName))) {
        return br.readLine();
    }
}

It is possible to declare more than one resource in a try-with-resource statement. They have to be separated by a semicolon:

Example 4.2. Multiple Resources in the Try-with-Resources Statement

try (FileReader f = new FileReader("a.txt");
        BufferedReader br = new BufferedReader(f)) {
    ...
}

5. Handle Multiple Exceptions in one Block

In Java SE 7 and later, a single catch block can handle more than one type of exception. This feature can reduce code duplication and lessen the temptation to catch an overly broad exception.

If a catch block handles more than one exception type, then the catch parameter is implicitly final. 

It is possible to combine exceptions in a multi-catch block that are not directly related (regarding inheritance)

Example 5.1. Java Try-Catch Multiple Exceptions in one Block

try {
   // ...
} catch (IOException | SQLException e) {
   e.printStackTrace();
}

 

Sources:  SCJP Sun Certified Programmer for Java 6 Exam 310-065

Java 8 Programmer II Study Guide, Exceptions by Esteban Herrera

Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking



0 comments
Leave your comment: