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;
<strong>try {</strong>
scan1 = new Scanner(new File("File1.txt"));
scan2 = new Scanner(new File("File2.txt"));
// Do useful stuff
<strong>} catch (IOException e) {</strong>
// Oops!
<strong>} finally {</strong>
scan1.close();
scan2.close();
System.out.println("Done!");
<strong>}</strong>
}
}
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:
<strong>try {</strong>
scan1 = new Scanner(new File("File1.txt"));
scan2 = new Scanner(new File("File2.txt"));
// Do useful stuff but also …
<strong>scan1.close();</strong>
<strong>scan1 = null;</strong>
<strong>} catch (IOException e) {</strong>
// Oops!
<strong>} finally {</strong>
scan1.close();
scan2.close();
System.out.println("Done!");
<strong>}</strong>
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[]) {
<strong>try (Scanner scan1 = new Scanner(new File("File1.txt"));</strong>
<strong>Scanner scan2 = new Scanner(new File("File2.txt"))) {</strong>
// 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.