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

3

We know of the need to close resources (files, connections, also called resources ) consumed in Java, such as OutputStream and InputStream . When we do not close them, we create performance issues and prevent the Garbage Collector from freeing up memory and finishing the Object, among other problems like memory leaks.

try-catch-finally language

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

This code opens a file, reads its lines, printa each, 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 force us to add the block finally , which is important to close the BufferedReader and all other IO objects associated with it, with or without exceptions and errors. Without finally our code can perfectly compile, run in test environments, and only reveal the failure to produce.

Since you do not need to include finally and still close Connection s, Statement s, ResultSet s, Reader s, Writer if even our objects that require a method of closing - close() ?

    
asked by anonymous 28.06.2015 / 17:04

1 answer

2

We must use the try-with-resources language

Also known as try-with-resourses statement , this artifice is available from version 1.7 of the Java SE platform.

How?

In try-with-resources , we can write code to be used by application, such as Connection s and files. Since such classes implement the interface AutoCloseable .

By using objects that implement AutoCloseable , you can apply a new language, where no more than finally is required. The compiler infers the block, ensuring that the resources are closed. This interface has a single method - close() , where in it, the programmer provides the 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 how does the code stay?

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();
}

What if the programmer does finally anyway?

No problem, what is written in finally is unified with the call to close() that is inferred by the compiler, so if you call close() in your finally , it will execute two times.

  

Since you do not need to include finally and still close Connection s, Statement s, ResultSet s, Reader s, Writer s, and even%   our objects in need of a method of closure -    close() ?

As we have seen, using try-with-resources language, it is possible to achieve this goal, even if our classes take advantage of this, AutoCloseable .

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

public void close() throws IOException;
    
28.06.2015 / 17:04