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