Fechar recursos automaticamente (Java 7) | Thiago Galbiatti Vespa
O Java 7 possui uma funcionalidade interessante para diminuir um pouco o código e evitar problemas em locais onde recursos precisam ser fechados (conexão com banco, manipulação de arquivos, sockets, streams em geral, ...). Essa funcionalidade é conhecida como try-with-resources.
Antes do Java 7, para ler um arquivo tínhamos que fazer o seguinte:
br = new BufferedReader(new FileReader("teste.txt"));
Com o uso do try-with-resources, podemos eliminar o "fechamento" do arquivo:
try (BufferedReader br = new BufferedReader(new FileReader("teste.txt"))) {
Dentro dos parênteses do try devemos colocar a declaração de uma ou mais variáveis de classes que implementam a interface AutoCloseable. Para garantir que isso funciona, vamos criar uma classe que implementa a interface AutoCloseable:
public class AutoFechavel implements AutoCloseable {
System.out.println("Fechou!!!");
Agora vamos colocá-la dentro do novo try:
package br.com.thiagovespa.sample.java7;
try (AutoFechavel af = new AutoFechavel()) {
System.out.print("Ahh eu aqui. ");
A saída desse código será: "Ahh eu aqui. Fechou!!!". Demonstrando que após finalizar o bloco try, o método close() é chamado automaticamente.
Podemos também ter duas ou mais variáveis dentro do try. Juntando os dois exemplos, temos:
try (AutoFechavel af = new AutoFechavel();
"teste.txt"))) {
Como as classes antigas também foram modificadas para implementar a interface AutoCloseable, podemos também utilizar essa funcionalidade em classes que realizam conexão com o banco (ResultSet, PreparedStatement, Connection, ...) e com isso nossa vida fica bem mais fácil!
As variáveis declaradas dentro do try-with-resources são marcadas como final.
A classe da variável declarada deve implementar a interface AutoCloseable
O escopo da variável é somente dentro do bloco try (completo)
As variáveis tem que ter nomes diferentes se estiverem dentro de um mesmo bloco try
Os recursos são iniciados da esquerda pra direita (de acordo com a declaração) e são fechados da direita pra esquerda.
Se o recurso for nulo ele não é fechado
Se um recurso lançar exceção ao fechar, os outros recursos continuarão a serem fechados (exceção suprimida).
Quando as exceções forem suprimidas, você pode recuperá-las utilizando o método: Throwable.getSuppressed()(normalmente dentro do catch)
Um dos problemas comum é atribuir um novo valor para a variável utilizada dentro do try-with-resources:
br = new BufferedReader(new FileReader("novoArquivo.txt"));
Na linha 6 estamos atribuindo para uma variável final. Isso vai ocasionar erro de compilação. Na linha 10 temos um exemplo de como recuperar as exceções suprimidas.