Try-catch-finally blocks

The try-catch-finally is used to control the program reaction to error conditions. The Java system uses Errors indicate unrecoverable problems and Exceptions to indicate problem situation that are potentially possibly recoverable. An example of an Error is that the Java system has run out of memory and cannot continue. An example of an Exception is that the program cannot open a file because the file by that name cannot be found.

Exceptions are objects that are created and thrown by the application program, often by testing for failing preconditions. In this code snippet below we want to safely divide two numbers, and the precondition is that the denominator cannot be zero. Before performing the division the value of the denominator is tested and, if zero, a new IllegalStateException object is instantiated and thrown. There are many types of exception objects that can be used in different circumstances to describe different events, and it is even possible to define your own exception types.

if (denom == 0)
    throw new IllegalStateException("Cannot divide by zero");
result = numerator/demon;

The try-catch block is a programming structure that allows Exceptions to be caught and processed. Often we want to attempt a graceful recovery from a minor problem and allow the program to continue. The code that has the potential to throw an exception is contained in the body of the try statement, and the recovery code is in the body of the catch section. The try block also allows a finally clause that contains actions to always be performed regardless of whether an exception was thrown. Finally blocks usually contain code that cleans up resources and resets the program state so that it can be rerun again.

The following example contains a try-catch-finally block:

input = null;  1
try {
   input = new BufferedReader(new FileReader("mydata.ext"));  2
   /* do processing here */
} catch (Exception ex) {  3
   System.our.println("The file was not completely processed due to "+
                       ex.getMessage());  4
}  finally {
   if (input != null)
       input.close()  5


The input variable is first defined outside of the try block. We will use the input variable in both the try and finally code blocks, so we need to define this item in a parent scope that includes all places where the variable will be used.


Within the try code block we have statements that we know may possibly throw errors.


The catch block identifies the species of exception that we are able to handle. In this case we have selected the Exception base class, so all exceptions will be caught here. If we were more selective we could have chosen only to handle cases of IOException, and other exception types would have passed up the call stack, possibly to a higher level try-catch block.


Our error handling activity is to simply print an error message noting that something went wrong. More sophisticated error handling might include throwing another exception to be handled up the chain.


In the finally block we attempt to clean up resources. First we test that the input variable has a value. If the exception occurred when the file was being opened then the input variable would not have been set and would still have a null value. If the input variable has a non-null value then the file must have been opened, and now as a cleanup step we want to close it, regardless if an exception occurred or not.

Search the web for "Java try catch" to learn more about try-catch blocks.