Baixe o app para aproveitar ainda mais
Prévia do material em texto
Tratamento de Exceções Prof. Marco Túlio de Oliveira Valente Prof. César Francisco de Moura Couto Prof. Pedro Felipe A. Oliveira 2 Introdução § Programas devem tratar erros ou situações não previstas: § Exemplos: divisão por zero, indexação de um vetor além de seus limites, overflow em uma operação aritmética, memória insuficiente, disco cheio etc § Problema: formas convencionais “poluem” o programa com código para tratamento de erros § Chegando a 2/3 do código em alguns programas § Solução: exceções 3 Introdução § Exceção: erro ou um estado imprevisto, que não ocorre com freqüência § Idéia: remover o tratamento de erros do fluxo normal de execução, de forma a não “poluir” o código. § Tratador (ou Manipulador) de Exceção: bloco de código para onde a execução é desviada quando ocorre uma exceção § Primeira linguagem: PL/I (1964) § Atualmente: ADA, C++, Java etc § Exceções em linguagens de programação: § Como ativar uma exceção ? § Como especificar um tratador de exceções ? § Como exceções são propagadas? § Como retornar ao fluxo normal de execução ? 4 Tratamento de Exceções em C++ § Como ativar uma exceção em C++ ? § Através do comando throw <expressão> § Exemplo: class DivisaoPorZero { } ; double divisao (double x, double y) { if (y = = 0) throw DivisaoPorZero (); // ativa (ou levanta) exceção return x / y; } § throw: abandona execução do bloco corrente e passa a executar um tratador de exceções 5 Tratamento de Exceções em C++ § Como especificar um tratador de exceções em C++ ? § Através dos comandos: try { ..... } // comandos que podem ativar exceções catch (parâmetro formal) { ..... } // tratador catch (parâmetro formal) { ..... } § Exceções ocorridas no interior de um try são transferidas para o catch correspondente § Exemplo: try { ...... divisao (5.0, 0.0); // ativa uma exceção .......... } catch (DivisaoPorZero) { // “captura” exceção .....; cout << “divisão por zero”; ..... } 6 Tratamento de Exceções em C++ Sem Tratamento de Exceções: ok= AbraArquivo (nome); if (ok) { tam= TamanhoArquivo (nome); if (tam != 0) { p= AloqueMemoria (tam); if (p != NULL) { ..... } else { ....... } } else { ........ } } else { ....... } Com Tratamento de Exceções : try { abraArquivo (nome); tam= TamanhoArquivo (nome); p= AloqueMemoria (tam); ...... } catch (ExcecaoAberturaArquivo) { ....... } catch (ExcecaoTamanhoArquivo) { ...... } catch (ExcecaoAlocacaoMemoria) { ...... } § Exemplo: 7 Tratamento de Exceções em C++ § Como exceções são propagadas ? § Exceções são propagadas automaticamente, terminando cada um dos blocos e funções do programa, até se encontrar um tratador com parâmetro formal do mesmo tipo do objeto especificado na ativação da exceção. § Em outras palavras, procura-se na pilha de ativação de blocos e funções, o primeiro catch que trate a exceção ativada § Como um tratador é escolhido ? catch (A) { ... } // captura exceções da classe A e das subclasses de A catch (B) { .... } // captura exceções da classe B e das subclasses de B catch (...) { ... } // captura exceções de qualquer classe (catch-all) 8 Tratamento de Exceções em C++ void f (int a) { cout << "f-inicio "; try { divisao (5.0, a); } catch (Overflow) { cout << "f-over"; } cout << "f-fim "; } void g () { int a; cout << "g-inicio "; try { cin >> a; f (a); } catch (DivisaoPorZero) { cout << "g-div0 "; } cout << "g-fim "; } void main () { // Resultado: g (); // a= 1: g-inicio f-inicio f-fim g-fim } // a= 0: g-inicio f-inicio g-div0 g-fim Exemplo § Exemplo: 9 Tratamento de Exceções em C++ § Como retornar ao fluxo normal de execução após tratar uma exceção ? § Basta que encontre-se um bloco catch que trate o tipo da exceção levantada § Este bloco é então executado; § A exceção é desativada; § E a execução prossegue na linha seguinte ao bloco § Como reativar uma exceção dentro de um bloco catch ? § Através do comando throw § Exemplo: catch (A) { ..... throw; // reativa exceção do tipo A ..... } 10 Tratamento de Exceções em Java § Exceções são § Erros de tempo de execução § Objetos criados a partir de classes especiais que são "lançados" quando ocorrem condições excepcionais § Métodos podem capturar ou deixar passar exceções que ocorrerem em seu corpo § É obrigatório, para a maior parte das exceções, que o método declare quaisquer exceções que ele não capturar § Mecanismo try-catch é usado para tentar capturar exceções enquanto elas passam por métodos 11 Três tipos de erros § Erros de lógica de programação § Ex: limites do vetor ultrapassados, divisão por zero § Devem ser corrigidos pelo programador § Erros devido a condições do ambiente de execução § Ex: arquivo não encontrado, rede fora do ar, etc. § Fogem do controle do programador mas podem ser contornados em tempo de execução § Erros graves onde não adianta tentar recuperação § Ex: falta de memória, erro interno do JVM § Fogem do controle do programador e não podem ser contornados 12 Como causar uma exceção? § Uma exceção é um tipo de objeto que sinaliza que uma condição excepcional ocorreu § A identificação (nome da classe) é sua parte mais importante § Precisa ser criada com new e depois lançada com throw IllegalArgumentException e = new IllegalArgumentException("Erro!"); throw e; // exceção foi lançada! § A referência é desnecessária. A sintaxe abaixo é mais usual: throw new IllegalArgumentException("Erro!"); 13 Exceções e métodos § Uma declaração throws (observe o "s") é obrigatória em métodos e construtores que deixam de capturar uma ou mais exceções que ocorrem em seu interior public void m() throws Excecao1, Excecao2 {...} public Circulo() throws ExcecaoDeLimite {...} § throws declara que o método pode provocar exceções do tipo declarado (ou de qualquer subtipo) § A declaração abaixo declara que o método pode provocar qualquer exceção (nunca faça isto) public void m() throws Exception {...} § Métodos redefinidos não podem provocar mais exceções que os métodos originais 14 Fluxo § Uma exceção lançada interrompe o fluxo normal do programa § O fluxo do programa segue a exceção § Se o método onde ela ocorrer não a capturar, ela será propagada para o método que chamar esse método e assim por diante § Se ninguém capturar a exceção, ela irá causar o término da aplicação § Se em algum lugar ela for capturada, o controle pode ser recuperado 15 Captura e Declaração public class RelatorioFinanceiro { public void metodoMau() throws ExcecaoContabil { if (!dadosCorretos) { throw new ExcecaoContabil("Dados Incorretos"); } } public void metodoBom() { try { ... instruções ... metodoMau(); ... instruções ... } catch (ExcecaoContabil ex) { System.out.println("Erro: " + ex.getMessage()); } ... instruções ... } } instruções que sempre serão executadas instruções que serão executadas se a exceção não ocorrer instruções serão executadas se exceção não ocorrerou se ocorrer e for capturada 16 try e catch § O bloco try "tenta" executar um bloco de código que pode causar exceção § Deve ser seguido por § Um ou mais blocos catch(TipoDeExcecao ref) § E/ou um bloco finally § Blocos catch recebem tipo de exceção como argumento § Se ocorrer uma exceção no try, ela irá descer pelos catch até encontrar um que declare capturar exceções de uma classe ou superclasse da exceção § Apenas um dos blocos catch é executado try { ... instruções ... } catch (TipoExcecao1 ex) { ... faz alguma coisa ... } catch (TipoExcecao2 ex) { ... faz alguma coisa ... } catch (Exception ex) { ... faz alguma coisa ... } ... continuação ... 17 finally § O bloco try não pode aparecer sozinho deve ser seguido por pelo menos um catch ou por um finally § O bloco finally contém instruções que devem se executadas independentemente da ocorrência ou não de exceções try { // instruções: executa até linha onde ocorrer exceção } catch (TipoExcecao1 ex) { // executa somente se ocorrer TipoExcecao1 } catch (TipoExcecao2 ex) { // executa somente se ocorrer TipoExcecao2 } finally { // executa sempre ... } // executa se exceção for capturada ou se não ocorrer 18 A Classe Exception § Construtores de Exception § Exception () § Exception (String message) § Exception (String message, Throwable cause) [Java 1.4] § Métodos de Exception § String getMessage() § Retorna mensagem passada pelo construtor § Throwable getCause() § Retorna exceção que causou esta exceção [Java 1.4] § String toString() § Retorna nome da exceção e mensagem § void printStackTrace() § Imprime detalhes (stack trace) sobre exceção 19 Como pegar qualquer exceção § Se, entre os blocos catch, houver exceções da mesma hierarquia de classes, as classes mais específicas (que estão mais abaixo na hierarquia) devem aparecer primeiro § Se uma classe genérica (ex: Exception) aparecer antes de uma mais específica, uma exceção do tipo da específica jamais será capturado § O compilador detecta a situação acima e não compila o código § Para pegar qualquer exceção (geralmente isto não é recomendado), faça um catch que pegue Exception catch (Exception e) { ... } 20 Relançar § Às vezes, após a captura de uma exceção, é desejável relançá-la para que outros métodos lidem com ela § Isto pode ser feito da seguinte forma public void metodo() throws ExcecaoSimples { try { // instruções } catch (ExcecaoSimples ex) { // faz alguma coisa para lidar com a exceção throw ex; // relança exceção } } 21 Classes Bases § RuntimeException e Error § Exceções não verificadas em tempo de compilação § Subclasses de Error não devem ser capturadas (são situações graves em que a recuperação é impossível ou indesejável) § Subclasses de RuntimeException representam erros de lógica de programação que devem ser corrigidos (podem, mas não devem ser capturadas: erros devem ser corrigidos) § Exception § Exceções verificadas em tempo de compilação (exceção à regra são as subclasses de RuntimeException) § Compilador exige que sejam ou capturadas ou declaradas pelo método que potencialmente as provoca 22 Hierarquia
Compartilhar