What you may not know about the try-catch-finally construct in Java
- Details
- Written by Nam Ha Minh
- Last Updated on 10 July 2019   |   Print Email
This Java tutorial demystifies the try-catch-finally construct in Java programming language.
Typically, a try-catch-finally construct looks like this:
try { // code can throw exceptions } catch (Exception ex) { // exception hanlder } finally { // this block is always executed }
The interesting point is that, code in the finally block always gets executed regardless of what happens in the try block. That means whether the exceptions throw or not, the Java Virtual Machine always execute code in the finally block. Hence the finally is preferred to clean up resources such as closing files, network connections, database connections and so on.
Let’s see an example program that proves the characteristic of the finally block:
public class FinallyTest { public static void main(String[] args) { try { String firstArg = args[0]; System.out.println("First Argument: " + firstArg); } catch (IndexOutOfBoundsException ex) { System.out.println("There is no argument"); } finally { System.out.println("Finally gets executed"); } } }
Now, run this program using the following command line (no argument):
java FinallyTest
Output:
There is no argument Finally gets executed
And run it again with an argument passed from the command line:
java FinallyTest Hello
Result:
First Argument: Hello Finally gets executed
You see? Indeed, code in the finally block gets executed in both scenarios: exception and no exception.
To understand clearly about the benefit of using finally block, consider the following program that writes some text to a file:
import java.io.*; public class NameWriter { public static void main(String[] args) { FileWriter writer = null; try { writer = new FileWriter("Name.txt"); writer.write("Hello "); //1 String name = args[0]; //2 writer.write(name); //3 writer.close(); //4 } catch (IOException e) { e.printStackTrace(); } } }
Look, the line 4 will not be executed in case the line 2 causes an exception (IndexOutOfBoundsException if no argument is passed). If that happens, the try-catch block exits but the file remains opened as line 4 could not be reached.
So a good practice is using the finally block to close the file regardless of exceptions, as shown in the following updated code:
FileWriter writer = null; try { writer = new FileWriter("Name.txt"); writer.write("Hello "); //1 String name = args[0]; //2 writer.write(name); //3 writer.close(); //4 } catch (IOException e) { e.printStackTrace(); } finally { if (writer != null) { try { writer.close(); } catch (IOException ce) { ce.printStackTrace(); } } }
Similarly, the following code demonstrates closing a database connection in the finally block:
Connection conn = null; try { String dbURL = "jdbc:oracle:thin:tiger/scott@localhost:1521:DB"; conn = DriverManager.getConnection(dbURL); // execute SQL statements } catch (SQLException ex) { ex.printStackTrace(); } finally { try { if (conn != null && !conn.isClosed()) { conn.close(); } } catch (SQLException ex) { ex.printStackTrace(); } }
And the following code demonstrates closing a network connection in the finally block:
HttpURLConnection httpConn = null; try { URL url = new URL("http://www.codejava.net"); httpConn = (HttpURLConnection) url.openConnection(); // download files... } catch (IOException ex) { if (httpConn != null) { httpConn.disconnect(); } }
NOTE:
- The finally block can be used with the try block only (the catch block is missing), for example:
try { String firstArg = args[0]; System.out.println("First Argument: " + firstArg); } finally { System.out.println("Finally gets executed"); }
- The only case in which the finally block does not get executed is when a call to System.exit() appears either in the try block or catch block. For example:
try { String firstArg = args[0]; System.out.println("First Argument: " + firstArg); } catch (IndexOutOfBoundsException ex) { System.out.println("There is no argument"); System.exit(0); } finally { System.out.println("Finally gets executed"); }
I hope you have got something interesting about the try-catch-finally construct. To summary:
- Java Exception handling allows us to use try-catch, try-finally and try-catch-finally constructs.
- The finally block always gets executed regardless of exceptions thrown or not.
- The finally block is preferred to clean up resources such as closing files, network connections, database connections, etc.
- The finally block could not be reached if a System.exit(0) is encountered either in the try or catch block.
Other Java Exception Handling Tutorials:
- 5 Rules about Catching Exceptions in Java
- Getting Started with Exception Handling in Java
- How to create custom exceptions in Java
- How to throw exceptions in Java - the differences between throw and throws
- Java Checked and Unchecked Exceptions
- Java exception API hierarchy - Error, Exception and RuntimeException
- Understanding Exception Stack Trace in Java with Code Examples
- Understanding Java Exception Chaining with Code Examples
Comments