Translate

quinta-feira, 31 de janeiro de 2013

Java 7 - Bloco multi-catch

No artigo anterior demonstrei o novo try capaz de encerrar recursos sem requerer do programador linhas de códigos improdutivas para isso.

Em sequência a produtividade no tratamento de exceções, vamos explorar o bloco multi-catch.

Do que se trata?

O Java 7 incorporou também uma forma de capturar mais de um tipo de exceção desde que as exceções capturadas herdem em algum momento de sua genealogia a mesma superclasse.

O exemplo a seguir lança propositalmente uma das exceções como IOException, IOError e InternalError. Estas exceções têm em comum Throwable como superclasse, por isso podem ser unidas em um único bloco capaz de capturar estas exceções.

Exemplo 1 - Testando o bloco multi-catch

import java.io.IOError;
import java.io.IOException;

public class TestaMultiCatch {

    public static final int MINIMUM = 1;
    public static final int MAXIMUM = 15;
   
    public static void main(String[] args) {

        try {

            int randomValue = MINIMUM + (int) (Math.random() * MAXIMUM);
           
            if (randomValue <= 5) {
                throw new IOException("Ocorrido IOException");
            } else if (randomValue <= 10) {
                throw new IOError(new Throwable("Ocorrido IOError"));
            } else {
                throw new InternalError("Ocorrido InternalError");
            }
           

        } catch(IOException | IOError | InternalError e) {

            System.out.println(String.format("Falha lançada para teste: %s", e.getMessage()));

        }

    }

}


O lançamento da exceção é aleatório porque um valor aleatório entre 1 e 15 é gerado para randomValue. Logo após, são realizados testes de períodos numéricos para lançar as exceções variavelmente.

Importante: Se a superclasse de uma das exceções do exemplo for adicionada no mesmo catch, a exceção deve ser removida porque será capturada pela sua superclasse.

Até breve.

Java 7 - Auto encerramento de recursos com novo try

Já comentei de algumas novidades do Java 7, mas não posso deixar de falar sobre o seu novo try capaz de gerenciar o encerramento automático de recursos.

Em versões anteriores ao Java 7, quando um recurso é construído e aberto (como ocorre com arquivos, conexões de banco de dados e sockets) algumas linhas de códigos a mais são necessárias para em caso de erro ainda garantir o fechamento adequado do recurso para não deixá-lo aberto ad eternum na memória do aplicativo.

Exemplo 1 - Teste do antigo try

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TestaOldTry {

    public static void main(String[] args) {

        FileReader fileReader = null;
        BufferedReader bufferReader = null;

        try {

            fileReader = new FileReader("c:/temp/datafile.txt");
            bufferReader = new BufferedReader(fileReader, 1024);

            String record = null;

            while ((record = bufferReader.readLine()) != null) {

                System.out.println(record);

            }     

        } catch(IOException e) {

            System.out.println(String.format("Falha ao ler arquivo: %s", e.getMessage()));

        } finally {

            if (bufferReader != null) {

                try {
                    bufferReader.close();
                } catch(IOException e) {
                    System.out.println("Falha ao fechar bufferReader: " + e.getMessage());
                }

            }

            if (fileReader != null) {

                try {
                    fileReader.close();
                } catch(IOException e) {
                    System.out.println("Falha ao fechar fileReader: " + e.getMessage());
                }

            }

        }

    }

}


Observe o cuidado e excessividade de códigos empregados para garantir o fechamento dos recursos bufferReader e fileReader no bloco finally.

Eis a novidade...

No Java 7 foi incorporado um try opcional para gerenciar automaticamente o encerramento de recursos. Para isso ocorrer, é necessário conferir se a classe do recurso implementa a nova interface java.lang.AutoCloseable ou a interface java.io.Cloaseable, senão o novo try não funciona logo na compilação. Este comportamento impede o programador para não se esquecer de programar um método de encerramento no recurso a ser automaticamente encerrado pelo novo try.

Agora vamos ver como fica a utilização do novo try, também conhecido por try-with-resources.

Exemplo 2 - Teste do novo try

public class TestaNewTry {

    public static void main(String[] args) {

        try (FileReader fileReader = new FileReader("c:/temp/datafile.txt");
                BufferedReader bufferReader = new BufferedReader(fileReader, 1024)) {

            String record = null;

            while ((record = bufferReader.readLine()) != null) {

                System.out.println(record);

            }     

        } catch(IOException e) {

            System.out.println(String.format("Falha ao ler arquivo: %s", e.getMessage()));

        }
    }

}


Este novo código revela um algoritmo bem menor e ainda traz o mesmo efeito do algoritmo do primeiro exemplo.

O objetivo com este novo try é certamente reduzir o número de códigos de sua programação Java para torná-la mais produtiva.

Até mais.