O documento discute exceções em Java, incluindo: 1) O que são exceções e como são manipuladas, 2) Os três tipos de exceções - verificadas, erros e runtime, 3) O requisito de captura ou especificação para exceções verificadas.
UNIVERSIDADE ESTADUAL DOSUDOESTE DA BAHIA CURSO DE CIÊNCIA DA COMPUTAÇÃO
ALGORITMOS E PROGRAMAÇÃO II – 2014.2
Fábio M. Pereira
(fabio.mpereira@uesb.edu.br)
2.
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
4.
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
5.
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
6.
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
7.
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
9.
Requisito de capturao 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
10.
Os três tiposde 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
11.
Os três tiposde 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
12.
Os três tiposde 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
13.
Os três tiposde 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
14.
Os três tiposde 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
15.
Os três tiposde 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
16.
Ignorando captura ouespecificaçã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
18.
Capturando e manipulandoexceçõ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
Exemplo
•A primeiralinha 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
22.
Exemplo
•Isto ocorreporque 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
23.
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
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) {
}
26.
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
27.
Exemplo
•Ambos osmanipuladores 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
28.
Exemplo
•O primeiromanipulador, 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
29.
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
30.
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
Especificando as exceçõeslanç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
37.
Especificando as exceçõeslanç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:
38.
Especificando as exceçõeslanç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 {
40.
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
41.
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
42.
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;
43.
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;
}
44.
A classe Throwablee 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
45.
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
46.
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
47.
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
Acessando a pilhade 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
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
53.
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
54.
Referências
The JavaTutorial 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
55.
UNIVERSIDADE ESTADUAL DOSUDOESTE DA BAHIA CURSO DE CIÊNCIA DA COMPUTAÇÃO
ALGORITMOS E PROGRAMAÇÃO II – 2014.2
Fábio M. Pereira
(fabio.mpereira@uesb.edu.br)