Method close () in try and catch blocks is required?

5

I'm studying Java with database and after seeing a little more about this close() method and this protected block, I was a bit confused, because in some codes and articles I see that close() was not used in try / catch blocks because they are " auto-close " or something like that.

I also know that it is very important to use this method to save execution resources. At the end of the day, if I use close() within the block, am I committing functionality ambiguity since the block is in charge of closing the connection? Or am I doing the right thing?

    
asked by anonymous 25.07.2018 / 15:33

3 answers

6

First you need to know if all the code is correct. When it comes to this kind of thing I see a lot wrong.

Second, you need to see the context, because you might not want to close it, so you should not use it.

It is common in many cases to use close() in a try-catch as much as outside it. In fact, people use try-catch where they should not and have a great chance of using it wrong there. And if you need to, you should probably use a try with resources , and then you do not need to use close() because it will be called automatically and in the right way.

If you use a try-catch then close() should be used in finally which is where try with resources places internally.

In general, semrpe uses a class called closeable , that is, it has a close() method (actually only when it is part of the AutoCloseable ) should use try with resources . Except in cases where the idea is not to close in that location.

A very large part of memory problems is not using it this way.

Placing a close() where it will be called is not a big problem, it just will not do any good. Just because the person can do wrong% w / with resources it is necessary to check first if it is already closed that makes the code slower, although it makes very little difference. But it's ambiguous.

See more in documentation .

    
25.07.2018 / 15:55
4

The safest way to use close() is in an indirect way, with try-with- resources . Try-with-resources was introduced in Java 7 that was released in 2011. So if you're seeing older articles, they will not talk about this feature and will show you the old-fashioned management.

An example of using try-with-resources is this:

try (Connection con = getConnection()) {
    // Faz algo com a conexão.
}

The compiler will put a finally implicit blcoo to close the con object and already treat all special cases of exceptions in block try and exceptions being thrown by close() method. If you put blocks catch or an explicit block finally , the compiler will know how to combine everything harmoniously. See try-with-resources .

Calling close() within a block that already uses try-with-resources , although possible, does not usually make much sense, but would also hardly cause any harmful effect unless you try use the enclosed feature as if it were still open, obviously.

If you can not use try-with-resources for some reason, you'd rather do what the compiler would do if you used it: Call close() inside block finally . For example:

Connection con = null;
try {
    con = getConnection();
    // ... faz um monte de coisas.
} catch (SQLException e) {
    // Faz algo para tratar a exceção, relançar ou encapsular e lançar outra exceção.
} finally {
    try {
        if (con != null) con.close();
    } catch (SQLException e) {
        // Faz algo para tratar a exceção, relançar ou encapsular e lançar outra exceção.
    }
}

If you are dealing with a case where the resource should remain open after finishing the method execution, then in general there are two alternatives:

  • Return the object that represents the resource that was left open so that the method that called it is concerned with closing.

  • Store the object in some class instance attribute and have this class implement AutoCloseable . The close() method of this class then delegates to close() of the open resource. This feature should preferably be opened in the constructor.

  • Example of case 1:

    // Deixa o recurso aberto e o retorna.
    public InputStream abrirArquivo() {
        return new FileInputStream(new File("teste.txt"));
    }
    
    // Usa o recurso aberto pelo outro método.
    public class utilizaArquivo() {
        try (InputStream x = abrirArquivo()) {
            // ...
        }
    }
    

    Case 2 Example:

    public class ChamadaTelefonica implements AutoCloseable {
        private final String destino;
        private final InputStream entrada;
        private final OutputStream saida;
    
        public ChamadaTelefonica(String destino) {
            this.destino = destino;
            this.entrada = ...;
            this.saida = ...;
        }
    
        // Um monte de métodos legais aqui que operar os atributos entrada e saída.
    
        @Override
        public void close() throws IOException {
            try {
                entrada.close();
            } finally {
                saida.close();
            }
        }
    }
    
        
    25.07.2018 / 16:44
    3

    You do not need to use close() to close a connection when it is managed by another system. It is common in large projects that connections are managed by servidor de aplicação , or by framework JPA , in this case it is not necessary to open or close connections, just to get and use.

    If you are doing everything manually, open connection, execute query, commit, etç, it is necessary and fundamental to close the connections, otherwise you can break the bank limit. This limit depends on the type of bank and configuration you are using.

        
    27.07.2018 / 16:11