content
- Resource management with Try-Catch-Finally, old style
- Try-with-resources
- Manage multiple resources
- Custom AutoClosable implementation
Try-with-resources is a new exception handling mechanism in java 7 that makes it easier to properly close resources used in try-catch blocks.
Resource management with Try-Catch-Finally, old style
Before java 7, managing resources that needed to be closed explicitly was quite tedious.
Take a look at the following method, which reads a file and prints it to System.out:
private static void printFile() throws IOException {
InputStream input = null;
try {
input = new FileInputStream("file.txt");
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
} finally {
if(input != null){
input.close();
}
}
}
new FileInputStream("file.txt");
There are four places where exceptions , int data = input.read();
, , data = input.read();
, may be thrown in the above code input.close();
.
The block is always executed regardless of whether try
the block throws an exception or not . finally
That is, no matter try
what happens to the fast seed, InputStream
it will be closed. close()
However, the method may also throw an exception if the shutdown fails .
Think about it, if an exception is thrown try
inside the block, and the finally
block also throws an exception, which exception do you think will be passed up the call stack.
finally
Exceptions thrown from the block will be passed up the call stack, even though try
exceptions thrown by the block may be related to the pass.
Try-with-resources
In Java 7 you can use the Try-with-resources construct to write the code in the above example:
private static void printFileJava7() throws IOException {
try(FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while(data != -1) {
System.out.print((char) data);
data = input.read();
}
}
}
Notice the first line of the method:
try(FileInputStream input = new FileInputStream("file.txt")) {
This is a try-with-resources
structure. Declare and instantiate in parentheses after the try keyword FileInputStream
.
When the try block ends, it FileInputStream
will automatically close. Because FileInputStream
the java.lang.AutoCloseable
interface is implemented, all classes that implement the interface can use the try-with-resources
structure.
If an exception try-with-resources
is thrown from the block, and when FileInputStream
closed (when close() is called), the exception in the try block is thrown to the outside world, and the exception thrown on FileInputStream
close is suppressed. This is the opposite of the previous example.
Manage multiple resources
You can try-with-resources
use multiple resources in a block and have them all closed automatically. Here is an example:
private static void printFileJava7() throws IOException {
try( FileInputStream input = new FileInputStream("file.txt");
BufferedInputStream bufferedInput = new BufferedInputStream(input)
) {
int data = bufferedInput.read();
while(data != -1){
System.out.print((char) data);
data = bufferedInput.read();
}
}
}
This example creates two resources in parentheses, one FileInputStream
and one BufferedInputStream
.
When the try block is finished executing, both blocks will be closed.
These resources will be closed in the reverse order in which they were created/listed within the parentheses, i.e. closed first BufferedInputStream
, then closed FileInputStream
.
Custom AutoClosable implementation
try-with-resources
Structs are not only applicable to java built-in classes, you can also implement interfaces in your own classes, java.lang.AutoCloseable
and you can use try-with-resources
interfaces.
AutoClosable
There is only one method named close()
in the interface, and the interface looks like this:
public interface AutoClosable {
public void close() throws Exception;
}
Any class that implements this interface can be try-with-resources
used with . Here is a simple example:
public class MyAutoClosable implements AutoCloseable {
public void doIt() {
System.out.println("MyAutoClosable doing it!");
}
@Override
public void close() throws Exception {
System.out.println("MyAutoClosable closed!");
}
}
doIt()
A method is not AutoClosable
part of an interface, it exists because we want to do more than just close the object.
Below is an example used MyAutoClosable
with try-with-resources
structs:
private static void myAutoClosable() throws Exception {
try(MyAutoClosable myAutoClosable = new MyAutoClosable()){
myAutoClosable.doIt();
}
}
When we call myAutoClosable()
the method, the output is as follows:
MyAutoClosable doing it!
MyAutoClosable closed!
As you can see, whether these resources are of your own creation or built-in components of Java, is a powerful way to try-with-resources
ensure that resources used inside blocks are properly closed .try-catch
Original link: http://tutorials.jenkov.com/java-exception-handling/try-with-resources.html#using-multiple-resources