domingo, 16 de março de 2014

Dando um close no Java 7: AutoCloseable

Gerenciar recursos sempre foi algo muito chato, principalmente quando parte do ciclo de vida do objeto é fecha-lo, senão você poderá ter problemas na execução do seu programa. Vamos por exemplo analisar um código que abre um arquivo e itera sobre ele exibindo seu conteúdo linha a linha:
        FileReader readerAntigo = null;
        try {
            readerAntigo = new FileReader("arquivo.txt");
            Scanner scanner = new Scanner(readerAntigo);

        while(scanner.hasNext()) {
            System.out.println(scanner.next());
        }
        } catch (FileNotFoundException e ) {
            System.out.println("Arquivo não encontrado");
        } finally {
            try {
                readerAntigo.close();
            } catch (IOException e) {
                System.out.println("Erro ao fechar o arquivo");
            }
        }
Perceba como é chato gerenciar o arquivo, para que eu possa abrir e fechar são necessário duas capturas de sessão, sem contar que ainda é necessário que o programador lembre-se de fechar o arquivo, algo que não pode ser tão crítico, mas se imaginarmos conexões JDBC, logo o banco começará a recusar conexões pois esquecemos de fecha-las anteriormente.

Para ajudar a solucionar isso, no Java 7 foi introduzi o AutoCloseable, que permite que recursos existam apenas dentro de um bloco e ao seu final (ou caso seja lançado uma exceção) sejam fechados devidamente. Para isso, foi criada a interface AutoCloseable, e o a classe que a implementada de sobrescrever o método close(). Ao abrir um novo recurso, você deve declara-lo e instancia-lo dentro de parentes após o try, ficando assim:

        try (ClasseAutoCloseable objeto = new ClasseAutoCloseable(...)) {
            //Dentro deste escopo o objeto existirá
            //ao final será chamado o método close() da interface AutoCloseable
        } catch (Exception e ) {
            //Caso tenha uma exception, também será dado o close()
        } 
Desta forma podemos eliminar em muito os blocos finally's que existem apenas para fechar recursos abertos, pois agora ele será fechado automaticamente.

Nosso exemplo acima, que abre e exibe o arquivo, ficando bem inferior a quantidade de linhas e mais simples de ler:

        try(FileReader reader = new FileReader("arquivo.txt")) {
            Scanner scanner2 = new Scanner(reader);
            scanner2.forEachRemaining(System.out::println); //Esse recurso surgiu no Java 8!
        } catch(IOException e) {
            System.out.println("Erro ao fechar o arquivo");
        }
Essa abordagem já esta usada em linguagens como C#, e agora o Java também possui este recurso que facilita em muito a vida do desenvolvedor.

Nenhum comentário:

Postar um comentário