aula tratamento de exceções

55
UNIVERSIDADE ESTADUAL DO SUDOESTE DA BAHIA CURSO DE CIÊNCIA DA COMPUTAÇÃO ALGORITMOS E PROGRAMAÇÃO II – 2014.2 Fábio M. Pereira ([email protected])

Upload: fabio-moura-pereira

Post on 09-Jul-2015

191 views

Category:

Education


1 download

DESCRIPTION

Aula Algoritmos e Programação II - Tratamento de Exceções

TRANSCRIPT

Page 1: Aula Tratamento de Exceções

UNIVERSIDADE ESTADUAL DO SUDOESTE DA BAHIA CURSO DE CIÊNCIA DA COMPUTAÇÃO

ALGORITMOS E PROGRAMAÇÃO II – 2014.2

Fábio M. Pereira

([email protected])

Page 2: Aula Tratamento de Exceções

Roteiro

• O que é uma exceção?

• Requisito de captura ou especificação

• Capturando e manipulando exceções

• Especificando as exceções lançadas por um método

• Como lançar exceções

• Vantagens de exceções

Page 3: Aula Tratamento de Exceções
Page 4: Aula Tratamento de Exceções

O que é uma exceção?

• Exceção á uma abreviação para a frase “evento excepcional”

• Definição: – Uma exceção é um evento, que ocorre durante a execução de

um programa, que interrompe o fluxo normal de instruções do programa

• Quando um erro ocorre, dentro de um método, o método cria um objeto e o envia para o sistema de execução

• Este “objeto de exceção” contém informação sobre o erro, incluindo o seu tipo e o estado do programa quando o erro ocorreu – Criar uma exceção e enviá-la ao sistema de execução é o que

chamamos de lançar uma exceção

Page 5: Aula Tratamento de Exceções

O que é uma exceção?

• Após o método lançar uma exceção, o sistema de execução tenta encontrar alguma coisa para manipulá-la

• O conjunto de possíveis “coisas” para manipular uma exceção é a lista ordenada de métodos que são chamados para chegar ao método onde o erro ocorreu

– Esta lista de métodos é conhecida como pilha de chamada

main

Método com um manipulador de exceção

Método sem um manipulador de exceção

Método onde o erro ocorreu

Chamada de método

Chamada de método

Chamada de método

Page 6: Aula Tratamento de Exceções

O que é uma exceção?

• O sistema de execução busca na pilha de chamada por um método que contém um bloco de código que pode manipular a exceção

• Este bloco de código é chamado de manipulador de exceção

• A busca iniciar no método em que o erro ocorreu e continua através da pilha de chamada em ordem inversa na qual os métodos foram chamados

• Quando o manipulador apropriado é encontrado, o sistema de execução passa a exceção ao manipulador

• Um manipulador de exceção é considerado apropriado se o tipo do objeto de exceção lançado combina com o tipo que pode ser manipulado pelo manipulador

Page 7: Aula Tratamento de Exceções

O que é uma exceção?

• A escolha do manipulador de exceção é chamada de capturar a exceção

• Se a busca do sistema de execução na pilha de chamada não encontrar um manipulador de exceção apropriado, o sistema de execução e o programa são interrompidos

main

Método com um manipulador de exceção

Método sem um manipulador de exceção

Método onde o erro ocorreu

Busca pelo manipulador apropriado

Busca pelo manipulador apropriado

Lançamento de exceção

Envia exceção para frente

Captura alguma outra exceção

Page 8: Aula Tratamento de Exceções
Page 9: Aula Tratamento de Exceções

Requisito de captura o especificação

• Um código válido na linguagem Java deve honrar o Requisito de Captura ou Especificação

• Isto significa que o código que pode lançar certas exceções deve estar delimitado por um dos seguintes: – Uma instrução try que captura a exceção – o try deve fornecer

um manipulador para a exceção

– Um método que especifica que uma exceção pode ser lançada – o método deve fornecer uma cláusula throws que lista a exceção

• O código que falhar em honrar o requisito de captura ou especificação não será compilado

• Nem todas as exceções estão sujeita a este requisito – Para entender o porquê, precisamos analisar as três categorias

de exceções, onde apenas uma está sujeita ao requisito

Page 10: Aula Tratamento de Exceções

Os três tipos de exceções

• O primeiro tipo de exceção é a exceção verificada – Estas são condições excepcionais que uma aplicação bem escrita deve

antecipar e se recuperar delas

• Por exemplo, – Suponha que uma aplicação peça ao usuário por um nome de arquivo

de entrada, então abra o arquivo passando o nome ao construtor de java.io.FileReader

– Normalmente o usuário fornece um nome de um arquivo que possa ser lido e que exista, assim a construção do objeto FileReader é bem sucedida e a execução da aplicação procede normalmente

– Mas algumas vezes o usuário pode fornecer um nome de um arquivo que não exista e o construtor lança java.io.FileNotFoundException

– Um programa bem escrito irá capturar esta exceção e notificar o usuário do erro, possibilitando que ele entre com um nome de arquivo correto

Page 11: Aula Tratamento de Exceções

Os três tipos de exceções

• Exceções verificadas estão sujeitas ao requisito de captura ou especificação

• Todas as exceções são exceções verificadas, exceto aquelas indicadas por Error, RuntimeException e suas subclasses

Page 12: Aula Tratamento de Exceções

Os três tipos de exceções

• O segundo tipo de exceção é o erro

– Estes são condições excepcionais que são internas à aplicação e que a aplicação normalmente não pode antecipar ou se recuperar

• Por exemplo,

– Suponha que uma aplicação abra uma arquivo para entrada com sucesso, mas não consiga ler o arquivo por causa de uma falha de hardware ou de sistema

– A leitura mal sucedida ira lançar java.io.IOError

– Uma aplicação poderia escolher capturar esta exceção, de maneira a notificar o usuário do problema, mas também faria sentido para o programa imprimir um rastreamento de pilha e sair

Page 13: Aula Tratamento de Exceções

Os três tipos de exceções

• Erros não estão sujeitos ao requisito de captura ou especificação

• Erros são exceções indicadas por Error e suas subclasses

Page 14: Aula Tratamento de Exceções

Os três tipos de exceções

• O terceiro tipo de exceção é a exceção runtime – Estas são condições excepcionais que são internas à aplicação e

que a aplicação normalmente não pode antecipar ou se recuperar

– Normalmente representam erros no programa, como erros lógicos ou uso não apropriado de uma API

• Por exemplo, – Considerando a aplicação descrita anteriormente que passa um

nome de arquivo ao construtor FileReader

– Se um erro lógico causar um valor null ser passado para o construtor, este irá lançar NullPointerException

– A aplicação pode capturar esta exceção, mas provavelmente faz mais sentido eliminar o erro que causou a ocorrência da exceção

Page 15: Aula Tratamento de Exceções

Os três tipos de exceções

• Exceções runtime não estão sujeitas ao requisito de captura ou especificação

• Exceções runtime são aquelas indicadas por RuntimeException e suas subclasses

• Erros e exceções runtime são conhecidas como exceções não verificadas

Page 16: Aula Tratamento de Exceções

Ignorando captura ou especificação

• Alguns programadores consideram o Requisito de Captura ou Especificação uma falha grave no mecanismo de exceção e os ignoram usando exceções não verificadas no lugar de exceções verificadas

• Em geral isto não é recomendado

Page 17: Aula Tratamento de Exceções
Page 18: Aula Tratamento de Exceções

Capturando e manipulando exceções

• Onde veremos como utilizar os três componentes de manipulação de eventos: os blocos try, catch e finally

• O exemplo a seguir define e implementa uma classe chamada ListaDeNumeros

Page 19: Aula Tratamento de Exceções

Exemplo

Page 20: Aula Tratamento de Exceções

Exemplo

Page 21: Aula Tratamento de Exceções

Exemplo

• A primeira linha em destaque é a chamada a um construtor – O construtor inicializa um fluxo de saída em um arquivo

– Se o arquivo não puder ser aberto, o construtor lança uma IOException

• A segunda linha em destaque é uma chamada ao método elementAt da classe Vector, que lança uma ArrayIndexOutOfBoundsException se o valor de seu argumento for muito pequeno (menor que zero) ou muito grande (maior que o número de elementos existentes atualmente no Vector

• Se tentarmos compilar a classe ListaDeNumeros, o compilador irá imprimir uma mensagem de erro sobre a exceção lançada pelo construtor FileWriter, embora não mostre uma mensagem de erro sobre a exceção lançada por elementAt

Page 22: Aula Tratamento de Exceções

Exemplo

• Isto ocorre porque a exceção lançada pelo construtor, IOException, é uma exceção verificada, e a lançada pelo método elementAt, ArrayIndexOutOfBoundsException, é uma exceção não verificada

• Vamos agora escrever os manipuladores de exceção para capturar e manipular estas exceções

Page 23: Aula Tratamento de Exceções

O bloco try

• O primeiro passo na construção de um manipulador de exceções é delimitar o código que pode lançar uma exceção dentro de um bloco try que, em geral, se parece com: try {

código

}

blocos catch e finally ...

• O segmento rotulado código contém uma ou mais linhas de código que poderiam lançar uma exceção

• Podemos colocar cada linha de código que pode lançar uma exceção dentro de seu próprio bloco try e fornecer manipuladores de exceção separados para cada uma ou colocar todo o código dentro de um único bloco try e associá-lo a múltiplos manipuladores

Page 24: Aula Tratamento de Exceções

Exemplo

Page 25: Aula Tratamento de Exceções

Os blocos catch

• Se uma exceção ocorrer dentro do bloco try, a exceção é manipulada pelo manipulador de exceção associado a ele – Para associar um manipular de exceção com um bloco try, devemos

colocar um bloco catch logo após ele

• Devemos colocar um ou mais blocos catch após o bloco try

– Não pode haver código entre o final do bloco try e o início do primeiro bloco catch:

try {

} catch (TipoDeExceção nome) {

} catch (TipoDeExceção nome) {

}

Page 26: Aula Tratamento de Exceções

Os blocos catch

• Cada bloco catch é um manipulador de exceção e manipula o tipo de exceção indicado em seu argumento

– O tipo do argumento, TipoDeExceção, declara o tipo de exceção que o manipulador pode manipular e deve ser o nome de uma classe que herda da classe Throwable

– O manipulador pode referenciar a exceção através de nome

• O exemplo mostra dois manipuladores de exceção para o método imprimeLista

Page 27: Aula Tratamento de Exceções

Exemplo

• Ambos os manipuladores imprimem uma mensagem de erro, mas o segundo não faz mais nada além disso, capturando uma IOException que não for capturada pelo primeiro manipulador, ele permite que o programa continue a sua execução

Page 28: Aula Tratamento de Exceções

Exemplo

• O primeiro manipulador, além de imprimir uma mensagem, lança uma exceção definida pelo usuário, ExcecaoExemplo

– Usamos isto quando queremos que o programa manipule uma exceção de uma maneira específica

• Manipuladores de exceção podem fazer mais que apenas imprimir uma mensagem de erro ou abortar o programa

– Elas podem se recuperar do erro, pedir para o usuário tomar uma decisão ou propagar o erro para um nível mais alto de manipulação usando exceções encadeadas

Page 29: Aula Tratamento de Exceções

O bloco finally

• O bloco finally sempre é executado quando o programa sai do bloco try

– Isto garante que o bloco finally seja executado mesmo que uma exceção não esperada ocorra

• finally é útil para evitar que código de limpeza seja eventualmente ignorado por um return, continue ou break

– Colocar código de limpeza em finally é sempre uma boa prática, mesmo que nenhuma exceção seja antecipada

• O método imprimeLista abre um PrintWriter

– Devemos garantir que o programa feche o arquivo antes de sair do método

Page 30: Aula Tratamento de Exceções

O bloco finally

• Isto pode ser complicado, uma vez que o bloco try de imprimeLista pode sair em uma das três maneiras:

1. A instrução new FileWriter falha e lança uma IOException

2. A instrução vetor.elementAt(i) falha e lança uma ArrayIndexOutOfBoundsException

3. Tudo é executado e o bloco try sai normalmente

• O sistema de execução sempre executa instruções dentro do bloco finally independente do que aconteça no bloco try, sendo então um lugar perfeito para realizar limpeza

Page 31: Aula Tratamento de Exceções

Exemplo

Page 32: Aula Tratamento de Exceções

Colocando tudo junto

Page 33: Aula Tratamento de Exceções

Cenário 1 – uma exceção ocorre

Page 34: Aula Tratamento de Exceções

Cenário 2 – execução normal

Page 35: Aula Tratamento de Exceções
Page 36: Aula Tratamento de Exceções

Especificando as exceções lançadas por um método

• Algumas vezes é apropriado que o código capture exceções que possam ocorrer dentro dele

• Em outros casos, é melhor deixar um método mais acima na pilha de chamadas tratar a exceção

• Por exemplo, se estivermos fornecendo a classe ListaDeNumeros como parte de um pacote de classes, provavelmente não poderíamos antecipar as necessidades de todos os usuários do pacote

– Neste caso, é melhor não capturar a exceção e permitir que um método mais acima na pilha de chamadas lide com isso

Page 37: Aula Tratamento de Exceções

Especificando as exceções lançadas por um método

• Se o método imprimirLista não capturar as exceções verificadas que podem ocorrer dentro dele, o método deve especificar que ele pode lançar essas exceções

• Vamos modificar o método imprimeLista original para especificar as exceções que podem ser lançadas, em vez de capturá-las

• Programa original:

Page 38: Aula Tratamento de Exceções

Especificando as exceções lançadas por um método

• Para especificar que imprimeLista pode lançar duas exceções, adicionamos uma cláusula throws na declaração do método: public void imprimeLista() throws IOException,

ArrayIndexOutOfBoundsException {

• Lembrando que ArrayIndexOutOfBoundsException é uma exceção não verificada, assim, incluí-la na cláusula throws não é obrigatório: public void imprimeLista() throws IOException {

Page 39: Aula Tratamento de Exceções
Page 40: Aula Tratamento de Exceções

Como lançar exceções

• Antes de podermos capturar uma exceção, algum código em algum lugar deve lançá-la

• Qualquer código pode lançar uma exceção: o seu código, o código de um pacote escrito por outra pessoa, como os pacotes que vêm com a plataforma Java, ou o ambiente de execução Java

• Independentemente do que lança a exceção, ela é sempre lançada com a instrução throw

• A plataforma Java oferece inúmeras classes de exceção – Todas as classes são descendentes da classe throwable e todas

elas permitem aos programas diferenciar entre os vários tipos de exceções que podem ocorrer durante a execução de um programa

Page 41: Aula Tratamento de Exceções

Como lançar exceções

• Também podemos criar nossas próprias classes de exceção para representar problemas que podem ocorrer dentro das classes que escrevemos

• Na verdade, se desenvolvemos pacotes, podemos ter que criar o nosso próprio conjunto de classes de exceção para permitir aos usuários diferenciarem um erro que pode ocorrer em nosso pacote de erros que ocorrem na plataforma Java ou outros pacotes

Page 42: Aula Tratamento de Exceções

A instrução throw

• Todos os métodos usam a instrução throw para lançar uma exceção

• A instrução throw requer um único argumento: um objeto throwable

• Objetos throwable objetos são instâncias de qualquer subclasse da classe Throwable

• Aqui está um exemplo de uma instrução throw: throw algumObjetoThrowable;

Page 43: Aula Tratamento de Exceções

A instrução throw

• Vamos olhar para a instrução throw em contexto: – O seguinte método pop foi retirado de uma classe de objeto que

implementa uma pilha comum – O método remove o elemento do topo da pilha e retorna o objeto public Object pop() {

Object obj;

if (tamanho == 0) {

throw new EmptyStackException();

}

obj = objetoEm(tamanho - 1);

setObjetoEm(tamanho - 1, null);

tamanho--;

return obj;

}

Page 44: Aula Tratamento de Exceções

A classe Throwable e suas subclasses

• Os objetos que herdam da classe Throwable incluem descendentes diretos e descendentes indiretos (objetos que herdam de filhos ou netos da classe Throwable)

• Como podemos ver, Throwable tem dois descendentes diretos: Error e Exception

Page 45: Aula Tratamento de Exceções

A classe Error

• Quando uma falha de ligação dinâmica ou outra falha importante na máquina virtual Java ocorre, a máquina virtual gera um Error

• Programas simples, normalmente, não capturam ou lançam Errors

Page 46: Aula Tratamento de Exceções

A classe Exception

• A maioria dos programas lançam e capturam objetos que derivam da classe Exception

• Uma Exception indica que ocorreu um problema, mas não é um problema grave no sistema

• A maioria dos programas que escrevemos lançam e capturam Exceptions em oposição a Errors

• A plataforma Java define os muitos descendentes da classe Exception

• Estes descendentes indicam vários tipos de exceções que podem ocorrer

• Por exemplo, IllegalAccessException indica que um determinado método não pôde ser encontrado, e NegativeArraySizeException indica que um programa tentou criar uma matriz com um tamanho negativo

Page 47: Aula Tratamento de Exceções

A classe Exception

• Uma subclasse de Exception, RuntimeException, é reservada para as exceções que indicam o uso incorreto de uma API

• Um exemplo de uma exceção de tempo de execução é NullPointerException, que ocorre quando um método tenta acessar um membro de um objeto através de uma referência nula

Page 48: Aula Tratamento de Exceções

A hierarquia de classes Throwable

Page 49: Aula Tratamento de Exceções

Acessando a pilha de informação de rastreamento

• Um rastreamento de pilha fornece informações sobre o histórico de execução do segmento atual e lista os nomes das classes e métodos que foram chamados no momento em que ocorreu a exceção

• Um rastreamento de pilha é uma ferramenta de depuração útil que normalmente tiramos proveito quando uma exceção é acionada

• O exemplo seguinte mostra como chamar o método getStackTrace do objeto de exceção

Page 50: Aula Tratamento de Exceções

Acessando a pilha de informação de rastreamento

catch (Exception e) {

StackTraceElement elementos[] = e.getStackTrace();

for (int i=0, n=elementos.length; i<n; i++) {

System.err.println(elementos[i].getFileName()

+ ":" + elementos[i].getLineNumber()

+ ">> " + elementos[i].getMethodName()

+ "()");

}

}

Page 51: Aula Tratamento de Exceções
Page 52: Aula Tratamento de Exceções

Vantagens de exceções

• Separar o código de tratamento de erros de código “regular”

– Exceções fornecem os meios para separar os detalhes do que fazer quando algo fora do comum acontece da lógica principal de um programa

– Na programação tradicional, a detecção de erros, relatórios e manipulação conduzem frequentemente a código confuso

• Propagar erros na pilha de chamadas

– Uma segunda vantagem de exceções é a capacidade de propagar o erro relatando a pilha de chamadas de métodos

Page 53: Aula Tratamento de Exceções

Vantagens de exceções

• Agrupar e diferenciar tipos de erro

– Uma vez que todas as exceções lançadas dentro de um programa são objetos, o agrupamento ou categorização de exceções é um resultado natural da hierarquia de classes

– Um exemplo de um grupo de classes de exceção relacionadas na plataforma Java são aquelas definidas em java.ioIOException e seus descendentes

– IOException é o mais geral e representa qualquer tipo de erro que pode ocorrer durante a execução de I/O

– Seus descendentes representam erros mais específicos, por exemplo, FileNotFoundException significa que um arquivo não pôde ser localizado no disco

Page 54: Aula Tratamento de Exceções

Referências

The Java Tutorial Fourth Edition: A Short Course on the Basics

Sharon Zakhour, Scott Hommel, Jacob Royal, Isaac Rabinovitch, Tom Risser, Mark Hoeber

...............................................

Publisher: Addison Wesley Professional

Pub Date: September 29, 2006

Page 55: Aula Tratamento de Exceções

UNIVERSIDADE ESTADUAL DO SUDOESTE DA BAHIA CURSO DE CIÊNCIA DA COMPUTAÇÃO

ALGORITMOS E PROGRAMAÇÃO II – 2014.2

Fábio M. Pereira

([email protected])