Excepções

Propaganda
Excepções
Algoritmos e Tipos Abstractos de
Informação (ATAI)
O que é uma excepção
Uma excepção é um evento que ocorre durante a execução de um
programa que interfere no fluxo normal das instruções deste
programa.
Em Java, a ocorrência de erros durante a execução de um
programa não significa necessariamente que o programa termina.
A linguagem possui um mecanismo para indicar partes críticas num
programa e recuperar eventuais erros ocorridas nestas partes, sem
parar a execução do programa. Este mecanismo é designado por
Excepção (Exception).
Uma Excepção é um sinal gerado pela máquina virtual de Java em
tempo de execução do programa, que é comunicado ao programa
indicando a ocorrência de um erro recuperável.
2
Erro e Excepção em Java
Unchecked
3
Excepções Verificadas
excepções que são
verificadas pelo
compilador
derivam de Exception
4
Excepções não Verificadas
excepções que não são verificadas pelo
compilador derivam de RunTimeException
5
Erro e Excepção em Java
Erro

Um Erro (Error) em Java
corresponde a uma situação
para a qual nenhuma
recuperação é já possível.

Descreve erros internos e a
exaustão de recursos durante a
execução do programa.

Pouco se pode fazer se um erro
interno desses ocorrer, além de
notificar o utilizador e tentar
finalizar o programa
adequadamente.

Essas situações são bastante
raras.
Excepção

Uma Excepção (Exception)
corresponde a uma situação para a
qual a recuperação é possível.

È um sinal gerado (lançado) pela
máquina virtual de Java em tempo
de execução do programa, indicando
a ocorrência de um erro recuperável.

A captura e o tratamento de
Excepções contribui para a
proclamada robustez do código dos
programas Java, a par da tipificação
dos dados e o modelo de memória
sem apontadores.
ATAI
6
O que ocasiona uma Excepção

Muitos tipos de erros podem provocar uma excepção, como
por exemplo:
 Tentar aceder a uma tabela fora de seus limites,
 Tentar abrir um arquivo inexistente,
 Tentar ler um ficheiro para além do fim deste,
 Tentar abrir uma URL inexistente,
 Tentar dividir por zero,
 Tentar calcular a raiz quadrada de um número negativo.
7
Beneficios do uso de Excepções
 O uso de excepções não diminui o esforço necessário para se
detectar, reportar e manipular erros.
 O uso de excepções permite a separação do código fonte regular do
código responsável pelo tratamento das situações anómalas que
podem acontecer no programa.
 Relativamente ao uso da instrução if possui as seguintes vantagens:
 Separação entre o tratamento de erros e o algoritmo.
 Propagação dos erros através da pilha de execução dos
métodos.
 Divisão por grupos de erros organizados em hierarquia.
8
Lançamento de Excepção
 Quando ocorre um erro recuperável dentro de um método, este cria um
objecto da classe Exception e passa este objecto para o sistema de
execução do Java (runtime) - lança uma Excepção.
 Este objecto contém informações sobre a excepção (seu tipo e o estado do
programa quando o erro ocorreu).
 A partir deste momento, o sistema de execução do Java responsabiliza-se
por encontrar o código que trate o erro ocorrido.
 O sistema passa a procurar o código capaz de tratar a excepção.
 A lista de “candidatos” para este tratamento vem da pilha de chamadas de
métodos que antecederam o método que lançou a excepção.
 O sistema de execução do Java “percorre a pilha de chamadas, e começa
com o próprio método onde ocorreu o erro, na busca de um método que
possua um gestor de Excepção (catch) adequado.
9
Captura de Excepção





Se a excepção não for tratada e chegar à função main, o programa será
interrompido com uma mensagem de erro.
Um “gestor de excepção” é considerado adequado quando a excepção que
ele manipula é do mesmo tipo da excepção lançada.
Quando ele é encontrado, recebe o controle do programa para que possa
tratar o erro ocorrido.
Em outras palavras, diz-se que ele “capturou” a excepção (catch the
exception).
Se nenhum dos métodos pesquisados pelo sistema de execução possui
um gestor de excepções adequado, então o programa Java em questão é
abruptamente encerrado.
10
Tratamento de Excepções
A linguagem Java permite a descrição de situações de excepção de uma forma
normalizada através da utilização de 5 palavras chave correspondentes a
cláusulas especiais, a saber:
try
catch
finally
throw
throws
try
{
// Trecho crítico do programa
}
catch(Excepção1 e1)
{
// Tratamento da e1 do tipo Excepção1
}
catch(Excepção2 e2)
{
// Tratamento da e2 do tipo Excepção2
}
…..
finally
{
// o bloco opcional
// se existe executado sempre
}
11
Tratamento de Excepções
Cláusulas try – catch

try
O código do programa tal como seria escrito mesmo que garantidamente
não pudesse gerar qualquer erro, é colocado neste bloco.
Num bloco try passaremos a ter a possibilidade de detectar a ocorrência de
alguns possíveis erros no código.

catch(Identificador_da_excepção var_exc1)
É aqui escrito o código de tratamento da excepção identificada na cláusula
catch.
 var_exc1 é instância da excepção que foi gerada (e que pode ser
usada).
Podemos ter inúmeras cláusulas catch para o mesmo bloco try, cada uma
correspondendo a uma classe de excepção diferente.
12
Tratamento de Excepções
Cláusula finally

finally
O código aqui colocado será sempre executado caso surja ou não uma excepção em
try.
Este código pode fazer o fecho de ficheiros, libertar recursos alocados, ou manipular
variáveis.
Se foi detectada excepção em try
se existe uma cláusula catch local ao método, então o bloco catch é executado,
e só depois o bloco finally.
se não existe catch local para a excepção ocorrida, é executado o bloco finally
e, caso exista, a cláusula catch externa ao método que primeiro for encontrada
(por exemplo no método invocador).
Se a forma de saída do bloco try, for return, continue ou break, quer exista ou não
catch, o bloco finally é de imediato executado.
13
Lançamento explícito de Excepções
(throw e throws)
Torna-se por vezes necessário no código de um dado método, "lançar" explicitamente uma
excepção, ou seja, alertar explicitamente para uma situação de erro entretanto ocorrida na
execução de tal código.
Qualquer método tem a possibilidade de o fazer usando a cláusula throw e criando uma
instância de uma dada excepção usando new.
A linguagem Java requer que qualquer método que possa provocar a ocorrência de uma
excepção normal, faça:
Localmente o tratamento de tal excepção numa cláusula catch.
Declare explicitamente que pode lançar tal excepção embora não a trate
localmente.
Neste último caso, no cabeçalho do método devem ser explicitamente declaradas
todas as excepções que podem ser lançadas através de uma cláusula throws.
14
Exemplo1
(sem tratamento de Excepção)
Programa que lê dois inteiros
class Ex1{
e calcula a sua divisão
public static int divide(int a, int b)
{
return a/b;
}
public static void main(String[] args) {
int num1, num2;
System.out.println("Introduza o primeiro número");
num1=Le.umInt();
System.out.println("Introduza o segundo número");
num2=Le.umInt();
System.out.println(num1+ " / " + num2 + " = "+ divide(num1,num2));
}
}
Quando num2 é igual a 0, causa o seguinte erro:
java.lang.ArithmeticException: / by zero
at Ex1.divide(exemplo1.java:5)
at Ex1.main(exemplo1.java:15)
o programa termina abruptamente
15
Exemplo2
(com tratamento de Excepção no main)
class Ex2{
public static int divide(int a, int b)
{
Programa que lê dois inteiros
return a/b;
e calcula a sua divisão
}
public static void main(String[] args) {
int num1, num2;
System.out.println("Introduza o primeiro número");
num1=Le.umInt();
System.out.println("Introduza o segundo número");
num2=Le.umInt();
try
{
System.out.println(num1+ " / " + num2 + " = "+ divide(num1,num2));
}
catch (ArithmeticException e)
{
System.out.println("Não é possivel divisao por 0 ");
}
Quando num2 é igual a 0, aparece a seguinte
}}
mensagem:
Excepção é capturada no main
Não é possivel divisao por 0
Finished executing
Quando é executado o programa não termina, é mais
robusto !
16
Exemplo3
(com captura de Excepção no divide)
class Ex3{
public static int divide(int a, int b)
{
Programa que lê dois inteiros
try{
e calcula a sua divisão
return a/b;
}
catch (ArithmeticException e)
{
System.out.println("Não é possivel divisao por 0 ");
return -1; // não é boa solução
}
}
public static void main(String[] args) {
int num1, num2;
System.out.println("Introduza o primeiro número");
num1=Le.umInt();
System.out.println("Introduza o segundo número");
num2=Le.umInt();
int res = divide(num1,num2);
if (res!=-1)System.out.println(num1+ " / " + num2 + " = "+ res);
}
}
Quando num2 é igual a 0, aparece a seguinte
mensagem:
Excepção é capturada no divide
Não é possivel divisao por 0
Finished executing
17
Exemplo4
(com captura e lançamento de Excepção no divide e tratamento no
main)
class Ex4{
public static int divide(int a, int b) throws ArithmeticException
{
try{
Não é obrigatório para
return a/b;
RunTimeException
}
catch (ArithmeticException e){
System.out.print("Erro: ");
throw e;
}
}
public static void main(String[] args) {
int num1, num2;
System.out.println("Introduza o primeiro número");
num1=Le.umInt();
System.out.println("Introduza o segundo número");
num2=Le.umInt();
try {
System.out.println(num1+ " / " + num2 + " = "+ divide(num1,num2));
}
catch (ArithmeticException e)
{
System.out.println("Não é possivel " + e.getMessage());
}
}
}
Excepção é capturada no divide
Quando num2 é igual a 0, aparece a seguinte
mensagem:
Erro: Não é possivel / by zero
Finished executing
18
Exemplo5
(com lançamento de Excepção no divide e tratamento no main)
class Ex4{
public static int divide(int a, int b)
{
if (b==0) throw new ArithmeticException("Valor nulo!");
return a/b;
}
public static void main(String[] args) {
int num1, num2;
System.out.println("Introduza o primeiro número");
num1=Le.umInt();
System.out.println("Introduza o segundo número");
num2=Le.umInt();
try {
System.out.println(num1+ " / " + num2 + " = "+ divide(num1,num2));
}
catch (ArithmeticException e)
{
System.out.println("Não é possivel " + e.getMessage());
}
}}
Excepção é capturada no divide
Quando num2 é igual a 0, aparece a seguinte
mensagem:
Não é possivel Valor nulo!
Finished executing
19
Exemplo
class Exemplo{
public static void main (String[] args){
String codigo; char zona;
int distrito, valido = 0;
System.out.print ("Codigo do Produto (XXX para sair): ");
codigo = Le.umaString();
while (!codigo.equals ("XXX")) {
try {
zona = codigo.charAt(2);
distrito = Integer.parseInt(codigo.substring(3,5));
System.out.println ("Distrito " +distrito);
valido++;
}
catch (StringIndexOutOfBoundsException exception) {
System.out.println ("comprimento errado: " + codigo);
}
catch (NumberFormatException exception) {
System.out.println ("Distrito não é numérico: " + codigo);
}
System.out.print (" Codigo do Produto (XXX para sair): ");
codigo = Le.umaString();
}
System.out.println ("Codigos validos: " + valido);
}}
20
Modelo das Excepções
Modelo baseado em três operações:

Declaração das excepções




Lançamento de excepções




Indicação ao compilador o que pode correr mal durante a execução de um método.
Consiste na declaração das excepções que podem ocorrer durante a execução de um
método
Sintaxe: public voi meuMetodo() throws IOException, ArithmeticException …;
Um método poderá lançar as excepções que declarar
(excepto: RuntimeException ou Error)
Lançamento explicito
 Sintaxe1: throw new TheException ou
 Sintaxe2: TheException e = new TheException (); throw e;
Lançamento Implícito
Captura de excepções

ponto do código para o qual o controlo do programa é transferido quando a excepção
é lançada (try, catch, finally).
ATAI
21
Classificação das Excepções
RuntimeException
IOException
 Ocorre porque houve um erro de •Tentar ler além do final de um
programação.
arquivo
 Conversão explícita de tipo
(cast)
•Tentar abrir um URL incorrecto
 Acesso a elemento de uma
tabela além dos limites .
•Tentar encontrar um objecto Class
através de uma string que não
denota uma classe existente.
 Acesso de ponteiro nulo
22
Classes de Excepção em Java
java.util
java.lang
EmptyStackException
NoSuchElementException
ClassNotFoundException
ArithmeticException
CloneNotSupportedException
Object
ArrayStoreException
IllegalAccessException
Throwable
ClassCastException
InstantiationException
Exception
IllegalArgumentException
InterruptedException
IllegalMonitorStateException
NoSuchMethodException
IndexOutOfBoundsException
RunTimeException
NegativeArraySizeException
java.awt
AWTException
NullPointerException
java.io
IOException
SecurityException
23
Excepções mais comuns
ArithmeticException
Indica situações de erros em processamento
aritmético, tal como uma divisão inteira por 0.
ArrayStoreException
Indica tentativa de armazenamento de um objecto
não válido numa tabela
ArrayIndexOutOfBoundsException
indica a tentativa de acesso a um elemento de um
arranjo fora de seus limites -- ou o índice era
negativo ou era maior ou igual ao tamanho do
arranjo.
IndexOutOfBoundsException
Indica tentativa de usar um índice fora dos limite de
uma tabela
NullPointerException
indica que a aplicação tentou usar null onde uma
referência a um objeto era necessária
IOException
indica a ocorrência de algum tipo de erro em
operações de entrada e saída
NumberFormatException
indica que tentou-se a conversão de uma string
para um formato numérico, mas seu conteúdo não
representava adequadamente um número para
aquele formato.
NegativeArraySizeException
Indica tentativa de criar uma tabela com dimensão
negativa
NumberFormatException
indica que tentou-se a conversão de uma string para
um formato numérico, mas seu conteúdo não
representava adequadamente um número para aquele
formato.
StringIndexOutOfBoundsException
Indica tentativa de usar um índice numa string fora
dos limite destas
24
Declaração explicita de Excepções
Exemplo6 - uso de throws
class LePalavras {
public static void copiaPalavra(String [] tabPal, String palavra)
throws ArrayIndexOutOfBoundsException,
NumberFormatException {
int index;
System.out.print("Introduza um Indice :");
index = Integer.valueOf(Le.umaString().trim()).intValue();
tabPal[index]= palavra;
}
Este programa faz a leitura de uma sequência de
Palavras e armazenamento de cada uma na posição
de uma tabela cujo índice é introduzido pelo utilizador
(sem validação prévia).
25
Declaração explicita de Excepções
Exemplo6 - uso de throws
public static void main(String args[])
{
int index, cont=0;
final int MAX_PALAVRAS=5;
String palavra = "" ;
String[] tabPal = new String[MAX_PALAVRAS];
// Tabela de Palavras
do{
try {
System.out.print("\nIntroduza uma Palavra :");
palavra = Le.umaString();
copiaPalavra(tabPal, palavra);
}
catch (ArrayIndexOutOfBoundsException e){
System.out.println("Erro! indice ilegal");
}
catch (NumberFormatException e) {
System.out.println("Erro! é esperado um inteiro");
}
cont++;
}
while (cont<MAX_PALAVRAS);
System.out.println("Fim..");
}
}
26
Lançamento de Excepções por um método
Exemplo7 - uso de throw
class LetabInteiros{
static public int [] criaTabInt(int tamanho)
{
int [] tabInt = new int[tamanho];
for (int i = 0 ; i < tamanho; i++)
{
System.out.print("\n Introduza " + i +" valor" );
tabInt[i] = Le.umInt();
}
return tabInt;
}
criaTabInt

Cria uma tabela de inteiros dinamicamente.

Lê do teclado um conjunto de valores inteiros.

Coloca cada valor lido na tabela.
27
Lançamento de Excepções por um método
Exemplo7 - uso de throw (cont.)
public static int elementoEm (int [] s, int index)
throws ArrayIndexOutOfBoundsException
{
if (index < s.length && index > -1)
return s[index];
else
{
ArrayIndexOutOfBoundsException excepcao =
new ArrayIndexOutOfBoundsException("erro no método elementoEm..");
throw excepcao;
}

Independente de outras excepções que possam ocorrer na
execução, uma classe pode forçar o lançamento de excepções
ou relançar uma determinada excepção, para que possa ser
tratada em diferentes níveis.

No método elementoEm o lançamento da excepção é explícita
(ou programada) através do uso da instrução throw.
}
28
Lançamento de Excepções por um método
Exemplo7 - uso de throw (cont.)
public static void main(String args[]){
int [] tab;
int index, valor, tabMax;
boolean fim = false;
System.out.print("\n Introduza o tamanho da tabela:");
tabMax = Le.umInt();
tab = criaTabInt(tabMax);
do{
System.out.print("\n Introduza o indice:");
index = Le.umInt();
try {
valor = elementoEm(tab,index);
System.out.print("Valor na posicao: " +valor);
}
catch (ArrayIndexOutOfBoundsException e){
if ( index == -1)

Este programa lê um conjunto de inteiros para
fim = true;
else
uma tabela, em seguida retorna os valores
System.out.println(e);
lidos pela indicação do índice da tabela.
}
}

O programa termina quando o índice é
while (!fim);
negativo.
System.out.println("Fim..");
}
}
29
Lançamento de Excepções por um método
Exemplo8 - uso de throw (cont.)
public static int elementoEm(int [] s, int index)
throws ArrayIndexOutOfBoundsException { // retorna valor na posicao index
try
{
Alteração do método elementoEm
return s[index];
}
catch( ArrayIndexOutOfBoundsException e) // trata localmente a excepção.
{
if ( index >= s.length)
{
System.out.println("\nErro, indice ilegal. uso de indice 0");
index = 0;
return s[index];
}

Nesta variante do método elementoEm a excepção é capturada.
else

É feito o tratamento do caso de tentativa do uso de um índice superior a
throw e;
dimensão da tabela.
} // fim catch
}// fim método


Nesta situação o índice é posto a 0.
Para que seja possível o tratamento de índices negativos, no método main, a
excepção é novamente lançada, através do uso de throw.
30
Beneficios do uso de Excepções
O uso de excepções não diminui o esforço necessário para
detectar, reportar e manipular erros.
O uso de excepções permite a separação do código fonte regular
do código responsável pelo tratamento das situações anómalos
que podem acontecer no programa.
Relativamente ao uso da instrução if possui as seguintes
vantagens:
Separação entre o tratamento de erros e o algoritmo.
Propagação dos erros através da pilha de execução dos métodos.
Divisão por grupos de erros organizados em hierarquia.
31
Download