Baixe o app para aproveitar ainda mais
Prévia do material em texto
Tratamento de exceções Profª. Juliana Pinheiro Campos E-mail: jupcampos@gmail.com ENG10082 – Programação II Créditos: Prof. Gustavo Willam Pereira e Prof. Clayton Vieira Fraga Filho • Situações que impedem o funcionamento normal de um programa • Exemplos: Tentativa de abertura de um arquivo inexistente Execução de uma operação ilegal (e.g., divisão por zero) Tentar fazer um saque em uma conta sem saldo; Tentar dar baixa em um produto com quantidade insuficiente; 2 • Formas rudimentares de tratamento de exceções numa função em C: Abortar programa usando abort(): muito radical Retornar um valor indicando o erro Exemplo em C: if (UmaFuncao() == VALOR_DE_ERRO) /* Tratamento de erro */ else /* Programa prossegue normalmente */ 3 4 Problemas (C): Cada chamada de função que pode gerar uma exceção deve ser testada prejudicando a legibilidade Nem sempre o programador checa o valor retornado Nem sempre uma função pode retornar um valor indicando erro (e.g., uma função que pode retornar qualquer valor do tipo int ou bool) Construtores e blocos de inicialização não retornam nenhum valor 5 Tratamento de exceções em Java: Permite detectar erros e manipular esses erros, tratá-los. Porque usar? S im plic ida de e ho m o g e ne ida de : Exceções constituem uma maneira elegante e simples para tratamento de condições excepcionais durante a execução de um programa Java. L e g ib ilida de de c ó dig o : Usando exceções se destaca a clara separação entre o fluxo normal de execução do programa e tratamento de condições excepcionais. 6 Uma exceção em Java é um objeto da classe java.lang.Exception, ou de uma de suas subclasses. Como todo objeto, a exceção é capaz de armazenar dados nas suas variáveis de instância. Quando um erro ou situação anormal é encontrado durante a execução de um método, um objeto exceção é construído, e diversos dados sobre essa ocorrência são registrados nos campos desse objeto. Nesse momento, o método onde ocorreu a exceção aborta, e o controle da execução retorna ao método que o chamou. Além disso, por um mecanismo especial, o objeto exceção que foi construído é também enviado ao método chamador. Diz-se que o método onde ocorreu o erro "lança" a exceção para o método que o chamou. 7 Resposta a uma circunstância excepcional que surge enquanto o programa está sendo executado; Forma de transferir o controle do programa de uma parte do programa que gera um erro para outra parte do programa que faz o tratamento adequado de erros. Vantagem do mecanismo: não é necessário checar valores de retorno de métodos a cada chamada Formado por: Lançador de exceção (comando throw) Tratador de exceção (estrutura try-catch-finally) 8 De modo geral, um método que lance uma exceção deve declarar isto explicitamente usando a palavra throw s . Throws é usado para indicar que qualquer chamada à este método deve tratar as exceções lançadas pelo throws com try/catch. Ex: public void meuMetodo() throws SQLException, IOException {} A palavra throw é usada quando o problema (exceção) aparece, para lançar uma exceção no meio do seu código. Essencialmente, é um desvio para um conjunto de instruções Usa a palavra-reservada throw seguida por um objeto de uma classe de exceção indicando a natureza da exceção. Ex: … throw new IOException("Erro de IO!"); 9 L a n ç a r (T h ro w ) u m a e x c e ç ã o : ou o Java ou o seu programa sinalizam que algo de errado aconteceu. Tra ta m e n to d e e x c e ç ã o : a resposta a uma exceção através da execução de uma parte do programa especialmente escrita para esta exceção ◦ também chamada de interceptação (catch) de exceção O caso normal é tratado no bloco try enquanto que o caso excepcional é tratado no bloco catch 10 Nós “tentamos” (try) executar um fragmento de código que pode gerar uma exceção Se uma exceção ocorrer nós a “capturamos” (catch), passando a executar um código de tratamento da exceção. Ao fim da execução (finally), nós executamos código de término. 11 • Bloco de instruções no qual algumas exceções podem ser lançadas (ocorrer). • Usa palavra-reservada try seguido de um bloco de instruções entre chaves. • Chamadas de métodos que não lançam exceções podem (mas não precisam) ser colocadas dentro de blocos try. • Quando uma exceção é lançada, cada objeto criado dentro do bloco try até o ponto de lançamento é liberado. • Sintaxe: 12 12 try { <Instruções que podem lançar exceções>; } Tratador de exceção: captura exceções O bloco catch recebe um parâmetro da classe Exception É chamado de parâmetro do bloco catch e é um nome normalmente usado para este parâmetro Se uma exceção é lançada durante a execução de um bloco try este imediatamente termina e o controle passa para o bloco catch apropriado. 13 • Sintaxe: • Onde: <classe de exceção> é classe de exceção que o tratador pode capturar e <argumento> é um identificador que armazena o valor da exceção lançada 14 catch(<classe de exceção> <argumento>) { <instruções>; } Podem existir vários blocos catch seguindo um bloco try • Vários tipos de exceções são possíveis em um bloco. • Um para cada tipo de exceção : a escolha do apropriado é feita de forma parecida ao bloco case O bloco catch que casa com alguma exceção lançada tem suas instruções executadas • Se nenhuma exceção é lançada, todos os blocos catch são saltados • Um bloco catch com argumento da classe Exception é executado com o lançamento de qualquer exceção; por isso, se ele existir, ele deve ser o último bloco catch • Exceções não interceptadas podem causar o término do programa 15 Apesar de parecer com uma definição de método, o bloco catch não o é. Toda Exception tem um método getMessage ◦ Recupera a string dada ao objeto de exceção quando ela foi lançada. Um bloco catch é aplicável apenas para o bloco try que o precede ◦ Se nenhuma exceção é lançada, o bloco catch é ignorado. 16 Pode-se especificar um bloco finally que é sempre executado quando uma exceção é lançada ou não. O bloco finally deve vir após o último bloco catch Usado para liberar recursos que não poderão ser usados devido à ocorrência da exceção. Sintaxe: 17 finally { <instruções>; } 1. O bloco try executa sem problemas e nenhuma exceção é lançada. Neste caso o bloco finally executa logo após o bloco try. 2. Uma exceção é lançada após o bloco try e interceptada em um bloco catch. O bloco finally executa após o bloco catch. 1. Uma exceção é lançada e não há um bloco catch capaz de interceptá-la. O bloco finally é executado antes do fim do método O código que está depois dos blocos catch mas não dentro do bloco finally - não é executado nesta situação 18 Ex: Programa que captura um número inteiro n do teclado para fazer 1000/n. O que acontece quando eu não trato exceção e digito zero ou um número não inteiro? Veja o uso do finally quando uma exceção é lançada e quando não é... 19 Exemplo 20 Problema Classe que identifica o erro Índice de uma lista fora do intervalo permitido IndexOutOfBoundsException Problemas em operações aritméticas (como divisão por zero) Arithmetic exception Uso de referência que não aponta para nenhum objeto NullPointerException A aplicação tentou converter uma string para um dos tipos numéricos, mas que a cadeia não tem o formato adequado. NumberFormatException Sinais de que uma exceção de I / O de algum tipo ocorreu. IOException Suponha um métodoqualquer (por exemplo, main()) que chama um método g(): 21 Vamos admitir que no método f() podem ocorrer diversos erros ou situações excepcionais. Usando exceções, o método f() poderia ser escrito da forma abaixo. O comando throw é que se encarrega de lançar a exceção para o método chamador: 22 Agora o método f() não precisa mais determinar o que fazer quando cada caso de erro ocorrer. Ele precisa apenas detectar que o caso de erro ocorreu. A partir daí, ele constrói, e "lança" para o método g() que o chamou, um objeto especial da classe Exception (ou de alguma subclasse). Ao construir esse objeto, o método f() insere nele as informações que permitirão entender qual erro ocorreu, e qual era o estado da aplicação no momento do erro. Esse objeto poderá ser "capturado" pelo método g(), e "tratado" lá, ou mesmo ser novamente lançado por g() para ser capturado e tratado por quem o chamou, no caso o main(). 23 Vamos supor que exceções geradas por f(), do tipo ExcecaoA, devam ser capturadas e tratadas pelo método main(), e exceções do tipo ExcecaoB devam ser capturadas e tratadas no método g(). Nesse caso, os métodos main() e g() devem ser escritos assim: 24 25 Exceções do tipo B que ocorram em f() jamais chegam a main(), pois são sempre capturadas em g(). Mas as exceções do tipo A lançadas por f() não são capturadas em g(), e são por ele relançadas para main(), onde são finalmente capturadas e tratadas. 26 Informando o compilador que o método poderá lançar uma ou mais exceções No final do cabeçalho de um método que poderá lançar exceções, coloca-se a informação: 27 Na captura de exceção os blocos catch e finally são opcionais, mas não é permitido haver apenas o bloco try sem pelo menos um bloco catch ou um bloco finally associado. O bloco finally será sempre executado após o bloco try terminar normalmete, ou após os blocos catch executarem, mesmo que a saída desses blocos seja causada pelo lançamento de outra exceção não tratada, ou por comando return. O bloco finally somente não será executado se ocorrer uma chamada para terminar a JVM, com System.exit(0). 28 Tipicamente, o bloco finally conterá comandos de liberação de recursos alocados no bloco try (abertura de arquivos, de banco de dados, etc). Se esses comandos ficassem no final do bloco try, poderiam nunca ser executados em caso de lançamento de exceção. 29 Veja um exemplo completo abaixo: 30 Veja um exemplo completo abaixo: Slide 1 Slide 2 Slide 3 Slide 4 Slide 5 Slide 6 Slide 7 Slide 8 Slide 9 Slide 10 Slide 11 Slide 12 Slide 13 Slide 14 Slide 15 Slide 16 Slide 17 Slide 18 Slide 19 Slide 20 Slide 21 Slide 22 Slide 23 Slide 24 Slide 25 Slide 26 Slide 27 Slide 28 Slide 29 Slide 30
Compartilhar