How to not include Finally and still close IO Streams, Connections, Statements, and other Resources?

Asked

Viewed 143 times

3

We know the need to close resources (files, connections, also called Resources) consumed in Java, such as OutputStream and InputStream. When we don’t close them, we create performance problems and prevent the Garbage Collector from releasing memory and finishing the Object, among other problems such as memory Leaks.

Idiom Try-catch-Finally

Below we have the main language that contemplates the above mentioned scenario:

This code opens a file, reads its lines, printa each one, captures exception if it occurs, and finally in case of success or error, closes the resource, ie the file.

public static void main(String[] args) {
    BufferedReader br = null;
    try {
        String sCurrentLine;
        br = new BufferedReader(new FileReader("C:\\testing.txt"));
        while ((sCurrentLine = br.readLine()) != null) {
            System.out.println(sCurrentLine);
        }
    } catch(IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (br != null) br.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

In the above code the compiler does not require us to add the block finally, which is important to close the BufferedReader and all other IO objects associated with it, whether or not exceptions and errors have occurred. Without the finally our code can perfectly compile, run in test environments, and only reveal production failure.

How not to include the finally and still close Connections, Statements, ResultSets, Readers, Writers and even our objects that require a closure method - close()?

1 answer

2


We must use the language Try-with-Resources

Also known as Try-with-Sourses statement, this trick is available from version 1.7 of the Java SE platform.

Like?

In the Try-with-Resources, we can write code that uses Resources for application, such as Connections and files. Since such classes implement the interface AutoCloseable.

Through the use of objects that implement AutoCloseable, it is possible to apply a new language, where no more of the block is needed finally. The compiler infers the block, ensuring that resources are closed. This interface has a single method - close(), where in it, the programmer provides closing logic.

The good news is: from Java 1.7, classes like Reader, Writer, Connection, Statement, ResultSet and many others already implement this interface.

So what about the code?

The written code can be rewritten as follows:

try (BufferedReader br = new BufferedReader(new FileReader("C:\\testing.txt"))) {
    String sCurrentLine;
    while ((sCurrentLine = br.readLine()) != null) {
        System.out.println(sCurrentLine);
    }
} catch (IOException e) {
    e.printStackTrace();
}

And if the program triggers the finally even so?

No problem, what is written in finally is unified with the call to the close() which is inferred by the compiler, so if we call the close() in his finally, it will be executed twice.

How not to include the finally and still close the Connections, Statements, ResultSets, Readers, Writers and even Our objects that require a closure method - close()?

As we have seen, using the language Try-with-Resources, it is possible to achieve this goal, already in case our classes take advantage of it, just make them implement the interface AutoCloseable.

Note: There is also the interface Closeable, which is subinterface of AutoCloseable. But in his method close, one IOException is in your signature:

public void close() throws IOException;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.