How to Use a Java try Statement with Resources

By Barry A. Burd

Imagine a Java program that gets input from two different files or from a Scanner and a disk file. To make sure that you clean up properly, you put close method calls in a finally clause.

import java.io.File;

import java.io.IOException;

import java.util.Scanner;

 

public class Main {

 

public static void main(String args[]) {

Scanner scan1 = null;

Scanner scan2 = null;

try {

scan1 = new Scanner(new File("File1.txt"));

scan2 = new Scanner(new File("File2.txt"));

// Do useful stuff

} catch (IOException e) {

// Oops!

} finally {

scan1.close();

scan2.close();

System.out.println("Done!");

}

}

}

In theory, the computer always executes scan1.close() and scan2.close() no matter what goes wrong during execution of the try clause. But that’s theory. In reality, another programmer (not you, of course) might modify the code by closing scan1 in the middle of the try clause:

try {

scan1 = new Scanner(new File("File1.txt"));

scan2 = new Scanner(new File("File2.txt"));

// Do useful stuff but also …

scan1.close();

scan1 = null;

} catch (IOException e) {

// Oops!

} finally {

scan1.close();

scan2.close();

System.out.println("Done!");

}

Now you have a real predicament. Inside the finally clause, the value of scan1 is null. The call to scan1.close() fails, so the program throws a NullPointerException and stops running before reaching the call to scan2.close(). In the worst of circumstances, scan2 isn’t closed and your program has File2.txt locked up so that no other program can use the file.

When a program uses several resources (many files, a database and a file, or whatever) the buildup of try statements becomes quite complicated. You can make try statements within catch clauses and all kinds of crazy combinations. But Java has a better way to solve the problem: In Java 7 (and later versions of Java), you can create a try-with-resources statement. This code shows you how.

import java.io.File;

import java.io.IOException;

import java.util.Scanner;

 

public class NewMain {

 

public static void main(String args[]) {

try (Scanner scan1 = new Scanner(new File("File1.txt"));

Scanner scan2 = new Scanner(new File("File2.txt"))) {

// Do useful stuff

} catch (IOException e) {

// Oops!v

}

System.out.println("Done!");

}

}

In this code, the declarations of scan1 and scan2 are in parentheses after the word try. The parenthesized declarations tell Java to close scan1 and scan2 automatically after execution of the statements in the try clause. You can declare several resources inside one try statement’s parentheses. When you do, Java closes all the resources automatically after execution of the try clause’s statements. You can add catch clauses and a finally clause, if you want. You can access all kinds of resources (files, databases, connections to servers, and others) and have peace of mind knowing that Java will sever the connections automatically.

Life is good.