Tratamento de exceções em Java

8
Wilson Ventura Júnior - Análise e Desenvolvimento de Sistemas - Instituto Infnet Tratamento de Exceções em Java Uma exceção é uma indicação de um problema incomum que ocorreu durante a execução de um programa. Com o tratamento de exceções é possível continuar a execução do programa (sem encerrá-lo) depois de lidar com o problema. Programas robustos e tolerante a falhas são aqueles que podem lidar com problemas à medida que surgem e continuar executando. O tratamento de exceções aprimora a tolerância a falhas de um programa. Mesclar o código de tratamento de erro com o código do programa pode degradar seu desempenho porque realizaria testes frequentes para determinar se tarefas que podem gerar erros foram executadas corretamente a fim de que a próxima tarefa possa ser executada. O tratamento de exceções permite separar o código do tratamento do erro do código principal de execução, aprimorando a clareza do programa e melhorando sua capacidade de modificação. O tratamento de exceções é projetado para processar erros síncronos, o tratamento de exceções NÃO é projetado para processar problemas associados a eventos assíncronos, tais como E/S de disco, chegada de mensagem de rede, cliques de mouse ou pressionamento de teclas, que ocorrem paralelamente ao fluxo de controle do programa e independentemente dele. Pode ser difícil incluir um tratamento de exceções depois que um sistema foi implementado, portanto é preferível incorporar a estratégia de tratamento de exceções ao sistema desde o design no princípio do projeto. Hierarquia de exceções em Java Iniciada na classe Throwable (subclasse de Object) é seguida de duas subclasses, Exception e Error. A classe Exception e suas subclasses representam situações excepcionais que podem ocorrer em um programa e serem capturadas e tratadas pelo aplicativo. A classe Error e suas subclasses representam situações anormais que ocorrem na JVM e não devem ser capturados pelos aplicativos. Normalmente não é possível que aplicativos se recuperem de erros.

description

Estudo sobre tratamento de exceções em Java. Cláusula try catch finally; Claúsula throws; Hierarquia de exceções; Exceções verificadas e não cerificadas, catch-or-declare; Encadeamento de exceções; Criação de exceções personalizadas.

Transcript of Tratamento de exceções em Java

Page 1: Tratamento de exceções em Java

Wilson Ventura Júnior - Análise e Desenvolvimento de Sistemas - Instituto Infnet

Tratamento de Exceções em Java Uma exceção é uma indicação de um problema incomum que ocorreu durante a execução de um programa. Com o tratamento de exceções é possível continuar a execução do programa (sem encerrá-lo) depois de lidar com o problema. Programas robustos e tolerante a falhas são aqueles que podem lidar com problemas à medida que surgem e continuar executando. O tratamento de exceções aprimora a tolerância a falhas de um programa. Mesclar o código de tratamento de erro com o código do programa pode degradar seu desempenho porque realizaria testes frequentes para determinar se tarefas que podem gerar erros foram executadas corretamente a fim de que a próxima tarefa possa ser executada. O tratamento de exceções permite separar o código do tratamento do erro do código principal de execução, aprimorando a clareza do programa e melhorando sua capacidade de modificação. O tratamento de exceções é projetado para processar erros síncronos, o tratamento de exceções NÃO é projetado para processar problemas associados a eventos assíncronos, tais como E/S de disco, chegada de mensagem de rede, cliques de mouse ou pressionamento de teclas, que ocorrem paralelamente ao fluxo de controle do programa e independentemente dele. Pode ser difícil incluir um tratamento de exceções depois que um sistema foi implementado, portanto é preferível incorporar a estratégia de tratamento de exceções ao sistema desde o design no princípio do projeto.

Hierarquia de exceções em Java Iniciada na classe Throwable (subclasse de Object) é seguida de duas subclasses, Exception e Error.

A classe Exception e suas subclasses representam situações excepcionais que podem ocorrer em um programa e serem capturadas e tratadas pelo aplicativo. A classe Error e suas subclasses representam situações anormais que ocorrem na JVM e não devem ser capturados pelos aplicativos. Normalmente não é possível que aplicativos se recuperem de erros.

Page 2: Tratamento de exceções em Java

Wilson Ventura Júnior - Análise e Desenvolvimento de Sistemas - Instituto Infnet

Exceções verificadas e Exceções não verificadas

Na hierarquia de Exception, o tipo de uma exceção determina se ela é verificada ou não verificada. Exceções não verificadas costumam ser causadas por deficiências no código do programa. Exceções verificadas são causadas por condições que estão fora do controle do programa. Subclasses (diretas ou indiretas) de RuntimeException são exceções não verificadas. Subclasses que herdam de Exception mas não de RuntimeException são exceções verificadas. O programador precisa lidar com exceções verificadas, isso resulta em código mais robusto do que aquele que seria criado se fosse possível simplesmente ignorá-las. Por conta disso o requisito catch-or-declare é obrigatório. Ao contrário das exceções verificadas, o compilador não verifica se uma exceção não verificadas é capturada ou declarada, pois é possível impedir a ocorrência de tais exceções pela codificação adequada. Todas as subclasses que herdam de Exception são exceções verificadas exceto as que herdam de RuntimeException.

Instrução try catch e Cláusula throws

O compilador impõe um requisito catch-or-declare (capture ou declare) às exceções verificadas. Como as exceções verificadas devem ser capturadas ou declaradas (catch-or-declare), o compilador verifica toda chamada de método para determinar se o mesmo lança exceções verificadas. Se lançar, checa se a exceção é capturada por uma instrução try catch ou declarada em uma cláusula thows. Se o requisito capture ou declare não for satisfeito, o compilador emite uma mensagem de erro indicando que a exceção deve ser capturada ou declarada.

Classes que herdam de Error são consideradas como não verificadas. A Classe Throwable oferece os métodos getMessage(), que retorna uma mensagem descrevendo detalhes do problema ocorrido, e printStackTrace(), que envia para o fluxo de erro o rastreamento da pilha de execução indicando onde aconteceu o problema. Isso é frequentemente útil no processo de depuração.

Tratamento de Exceções

Clausula throws

Uma cláusula throws especifica quais exceções um método pode lançar, um método pode lançar exceções das classes listadas em sua cláusula throws ou de suas subclasses. Métodos que podem lançar exceções são definidos com a palavra-chave throws que especifica tais exceções declarando entre a lista de parâmetros e o corpo do método uma lista de exceções separadas por vírgulas que o método pode lançar caso ocorram. Caso haja um erro, o método encerra sua execução e a JVM lança um objeto do tipo especificado na cláusula que será capturado pelo bloco catch cujo tipo especificado no parâmetro seja correspondente e exibirá informações básicas sobre a exceção invocando implicitamente seu método toString(). A cláusula throws não deve ser confundida com a instrução throw,utilizada para lançar exceções.

Page 3: Tratamento de exceções em Java

Wilson Ventura Júnior - Análise e Desenvolvimento de Sistemas - Instituto Infnet

Instrução throw

Lançando exceções com a instrução throw Assim como as exceções lançadas pela JVM, é possível lançar exceções com a instrução throw , executada para indicar para os aplicativos que uma exceção ocorreu. throw new Exception();

Uma instrução throw especifica um objeto a ser lançado e seu operando pode ser de qualquer classe derivada de Throwable.

Instrução try catch [finally]

Bloco try

As instruções que podem lançar algum tipo de exceção (causar erro) devem ser colocá-las dentro do bloco try, caso não haja erro, serão são executadas normalmente e o controle do programa segue para a primeira instrução depois do último bloco catch ou para a execução do bloco finally , se houver. Caso ocorra alguma exceção, o código do bloco try não é executado e um objeto representando a exceção é criado e lançado a fim de ser capturado pelo bloco catch correspondente. Será executado o primeiro bloco catch cujo tipo de parâmetro corresponder (ou ser uma superclasse) à

exceção ocorrida e lançada pelo bloco try. Dentro do bloco try, o método lança um objeto exceção, um manipulador catch captura a exceção e dá o tratamento necessário. Exceções podem ser lançadas a partir do código do bloco try, por chamadas de métodos iniciadas no bloco

try (mesmo que aninhados) ou a partir da JVM à medida que executa os bytecodes. Modelo de terminação de Tratamento de Exceções do Java No Java, depois que uma exceção é tratada, o controle do programa não retorna ao ponto de lançamento porque o bloco try expirou e suas variáveis locais foram perdidas.

Algumas linguagens utilizam o Modelo de Retomada de Tratamento de Exceções em que o controle é retomado logo depois do ponto de lançamento.

Com o tratamento de exceções, caso o usuário cometa um erro na inserção de dados, o programa pode capturar esse erro e tratá-lo. É possível oferecer ao usuário a opção de que ele insira a entrada novamente com uma condição num laço. Dentro do(s) bloco(s) catch { }, a rotina Scanner.nextLine() descarta a entrada e o usuário pode inseri-la novamente. Caso a entrada seja correta a condição do laço é configurada como false dentro do bloco try { } e o programa segue normalmente.

Page 4: Tratamento de exceções em Java

Wilson Ventura Júnior - Análise e Desenvolvimento de Sistemas - Instituto Infnet

Bloco catch

É possível tratar uma determinada exceção, todas as exceções, as exceções de um certo tipo ou exceções de um grupo de tipos relacionados numa hierarquia de classes. Pelo menos um bloco catch obrigatório e um bloco finally opcional deve seguir um bloco try . Cada bloco catch pode ter apenas um único parâmetro. O parâmetro de exceção do bloco catch especifica que tipo de exceção o handler pode processar. Utilizar um nome de parâmetro de exceção que reflita o seu tipo, em oposição a variável 'e', promove clareza e é uma boa prática de programação. catch(ArithmeticException divisaoPorZero) {//...}

catch(InputMismatchException tipoIncompativel) {//...}

A ordem dos blocos catch é importante

Caso haja múltiplos blocos catch que correspondam a um tipo particular de exceção, somente o primeiro bloco

catch correspondente executará caso ocorra a exceção. Não podemos colocar uma superclasse (Exception) antes de uma subclasse, pois isso indicaria uma situação onde teríamos um tratamento de erro que nunca seria alcançado, já que a superclasse não deixaria o teste ser feito capturando todas as exceções de forma generalizada. Em contrapartida, capturar a superclasse no último bloco catch garante que os objetos de todas as subclasses sejam capturados.

Posicionar um bloco catch para tipo superclasse após todos os outros de subclasse assegura que todas as exceções de subclasse sejam por fim capturadas. Como qualquer bloco de código, quando um bloco try termina, suas variáveis locais saem de escopo e não são mais acessíveis. Logo, as variáveis locais de um bloco try não são acessíveis nos seus blocos catch correspondentes. O mesmo ocorre com as variáveis locais do bloco catch , quando um bloco catch termina, as variáveis locais declaradas também saem de escopo e são destruídas.

Bloco finally

O bloco finally (opcional) deve ser colocado após o último bloco catch. Sua utilização é indicada para liberação de recursos adquiridos num bloco try ou catch. Os programas que obtêm certos tipos de recursos devem retorná-los explicitamente ao sistema, a fim de evitar "vazamento de recursos", como vazamento de memória (apesar do Java ter coleta automática de lixo), arquivos ou conexões de BD ou conexões de rede que não são fechadas adequadamente.

Page 5: Tratamento de exceções em Java

Wilson Ventura Júnior - Análise e Desenvolvimento de Sistemas - Instituto Infnet

O bloco finally executa independentemente de uma exceção ser lançada.

Caso a exceção seja capturada, o comando passa para o bloco finally depois do último catch . Caso a exceção não seja capturada, o comando passa para o bloco finally depois do try , nessas duas opções os recursos adquiridos em cada bloco são liberados pela instrução dentro do bloco finally .

Capturando exceções de subclasse

Se um handler catch capturar objetos de exceção tipo superclasse, também pode capturar objetos de subclasse dessa classe. Caso o tratamento das exceções exija processamento diferente, é interessante capturar cada tipo de subclasse individualmente. Capturar exceções relacionadas com um handler tipo superclasse só faz sentido se o tratamento for o mesmo para todas as subclasses.

Exceções não tratadas Uma exceção para a qual não há nenhum bloco catch correspondente é uma exceção não capturada. Quando um método detecta um problema e é incapaz de tratá-lo, exceções são lançadas pela JVM e o rastreamento de pilha é exibido. O tipo de exceção é especificado e o rastreamento de pilha inclui o caminho da execução que resultou na exceção, método por método. A linha superior da cadeia de chamadas indica o ponto de lançamento inicial onde a exceção ocorreu. Cada linha do rastreamento de pilha contém pacote.Classe.metodo.arquivo.numDaLinha

Caso um programa tenha múltiplas Threads, uma exceção não capturada encerrará apenas a Thread em que ocorreu a exceção.

Exceções encadeadas Quando um método responde a uma exceção lançando um tipo de exceção diferente que é específica do aplicativo em uso, as informações da exceção original são anexadas às informações da nova exceção. Exceções encadeadas fornecem mecanismos para empacotar as informações da exceção original e do rastreamento de pilha, permitindo a um objeto exceção manter informações de rastreamento de pilha completas a partir da exceção original.

Page 6: Tratamento de exceções em Java

Wilson Ventura Júnior - Análise e Desenvolvimento de Sistemas - Instituto Infnet

public class ExcecoesEncadeadas {

public static void main( String[] args ) {

try {

method1(); // call method1

}

catch ( Exception excC ){ // exceptions thrown from method1

exc1.printStackTrace();

}

} // main

public static void method1() throws ExceptionC {

try {

method2(); // throw exceptions back to main

}

catch ( Exception excB ){ // exception thrown from method2

throw new ExceptionC( "Exception thrown in method1", excC );

}

} // method1()

public static void method2() throws ExceptionB {

try {

method3(); // throw exceptions back to method1

}

catch ( Exception excA ){ // exception thrown from method3

throw new ExceptionB( "Exception thrown in method2", excB );

}

} // method2()

public static void method3() throws ExceptionA {

// throw Exception back to method2

throw new ExceptionA( "Exception thrown in method3" );

} // method3()

}//class

Page 7: Tratamento de exceções em Java

Wilson Ventura Júnior - Análise e Desenvolvimento de Sistemas - Instituto Infnet

Criando uma nova exceção Para criar uma nova classe de exceção, esta deve estender uma classe de exceção existente, isso assegura que ela possa ser utilizada com o mecanismo de tratamento de exceções do Java. Ao definir seu próprio tipo de exceção, estude as Classes de exceção existente na API do Java e tente estender uma Classe de exceção relacionada. Uma nova Classe de exceção deve ser uma exceção verificada (estende Exception, mas não RuntimeException) caso a exceção precise ser tratada ou deve ser uma exceção não verificada (estender RuntimeException) se for possível ignorar a exceção. Por convenção todos os nomes de Classes de exceção devem terminar com a palavra Exception. Uma Classe de exceção pode conter campos e métodos. Uma nova Classe de exceção típica contém "somente quatro construtores":

1. Um construtor que não recebe nenhum argumento e passa uma mensagem de erro padrão String para o construtor da superclasse;

2. Um construtor que recebe uma String como mensagem de erro personalizada e a passa para o construtor da superclasse;

3. Um construtor que recebe uma String como mensagem de erro personalizada e um throwable (para exceções encadeadas) e passa ambos para o construtor da superclasse;

4. Um construtor que recebe um throwable (para exceções encadeadas) e o passa para o construtor da superclasse;

Procedimento para criar uma nova exceção

1. Cria-se uma nova Classe de Exceção estendendo-se uma Classe de exceção existente (Exception);

2. Implementa-se essa Classe com quatro opções de construtores típicos de Classes de exceções;

3. Cria-se uma Classe de testes para colocar o código do programa dentro de uma instrução try catch;

4. Coloca-se como argumento de um bloco catch { } um objeto do tipo ExcecaoCriada e dentro do bloco implementa-se o tratamento necessário ao erro;

Pré-condições e Pós-condições

São os estados esperados antes e depois da execução de um método, respectivamente. Uma pré-condição descreve restrições nos parâmetros e deve ser verdadeira quando um método é invocado. Caso não sejam satisfeitas, o comportamento do método será indefinido. Uma pós-condição é verdadeira depois que um método retorna com sucesso. Descrevem as restrições sobre o valor de retorno e quaisquer outros efeitos colaterais que o método possa apresentar. Se as pré-condições e pós-condições não forem satisfeitas, os métodos costumam lançar exceções.

Page 8: Tratamento de exceções em Java

Wilson Ventura Júnior - Análise e Desenvolvimento de Sistemas - Instituto Infnet

Exemplo: