Você está na página 1de 3

Laboratrios de Programao

Introduo s excees em Java


March, 23 2011, 15:59
Thibault Langlois
Uma exceo assinala a ocorrncia de uma situao especial, normalmente uma situao de erro, num programa Java. Quando
uma determinada situao detectada lanada uma exceo que deve ser tratada de forma correcta.
O mecanismo base para tratar excees no Java a instruo try-catch, composta por um bloco try e um ou mais blocos
catch. Mais precisamente, no bloco try encontram-se as instrues do programa que so susceptiveis de provocar um erro. O
bloco catch responsvel por apanhar um certo tipo de de exceo e executar uma sequncia de instrues adequadas que,
conforme os casos podem simplesmente avisar o utilizador ou remdiar ao problema caso seja possvel. este processamento que
designamos informalmente por tratar a exceo. Os dois tipos de blocos so indissociveis, i.e. no podemos usar um bloco catch
sem usar um bloco try, nem podemos usar um bloco try sem pelo menos um bloco catch.
As excepes podem ser de diversos tipos e o tipo da exceo lanada depende da situao detectada. No exemplo seguinte, o
lanamento de uma exceo da classe Exception feito dentro do bloco try usando explicitamente a instruo throw. Assim que
a exceo lanada, o bloco try termina e o bloco catch que tem capacidade para tratar excees daquele tipo, apanha a exceo
e trata-a.
int waitTime=46;
try {
System.out.println("Try-block entered.");
if (waitTime > 30)
throw new Exception("Time Limit Exceeded.");
System.out.println("Leaving try block.");
}
catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
System.out.println("After catch-block.");
Neste exemplo o bloco try :
try {
System.out.println("Try-block entered.");
if (waitTime > 30)
throw new Exception("Time Limit Exceeded.");
System.out.println("Leaving try block.");
}
E o bloco catch :
catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
A sada deste programa ser:
Try-block entered.
Exception: Time Limit Exceeded.
After catch-block.
Se a primeira linha do cdigo for substituda por int waitTime=20; a exceo no lanada e depois do bloco try terminar, o
programa executa o cdigo aps o bloco catch. O output neste caso ser:
Try block entered.
Leaving try block.
After catch-block.
Uma exceo uma instncia da classe java.lang.Exception ou de uma das suas subclasses como, por exemplo, IOException
e FileNotFoundException. O programador pode definir as suas prprias subclasses de Exception.
Um mtodo pode lanar uma exceo e trat-la com try-catch. Mas tambm pode lanar excees que ele prprio no trata.
Neste caso, a assinatura do mtodo deve explicitar este facto, como pode ver-se no exemplo seguinte, usando na sua assinatura a
palavra throws (notar o s no final da palavra) seguida dos nomes das excees lanadas e no tratadas. Quando o mtodo lana
uma exceo a sua execuo termina de imediato.
public void MyMethod(int n) throws IOException, MyExceptionClass
//esta ltima uma classe definida pelo programador
{
.
.
.
}

A invocao de um mtodo que lana excees que no as trata tem de ser efectuada numa das duas formas seguintes:
dentro de um bloco try cujo respectivo bloco catch trata as excees do tipo indicado na assinatura do mtodo;
no tratando as excees, mas lanando-as novamente. As excees podem ser lanadas pelos mtodos que no as tratam
at encontrar um mtodo que as trate ou, em ltima instncia, at chegar ao mtodo main. Este mtodo, por seu turno,
pode tratar as excees ou ter declarado na sua assinatura que lana esses mesmos tipos de excees. Neste ltimo caso as
excees so passadas ao utilizador assim que o programa termina a sua execuo.
O compilador controla o tratamento das excepes: assinala um erro sempre que possa ser lanada uma excepo que nem
tratada nem lanada novamente.
Suponhamos que o programador use dentro de um mtodo m de uma das suas classes o mtodo close, definido na classe
FileInputStream, e que tem a seguinte assinatura:
public void close() throws IOException
Ento, como descrito anteriormente, tem duas alternativas:
1) o mtodo m trata explicitamente as excees do tipo IOException dentro de um try-catch:
FileInputStream f;
...
try {
...
f.close();
...
}
catch (IOException e)
{
...
//tratamento da exceo
}
ou
2) anuncia que pode ser lanada uma exceo, apresentando uma assinatura do tipo :
public void m() throws IOException
O mecanismo de excepes tem como objectivo permitir o tratamento de cada tipo de erro de forma especfica. Existem portanto
vrias classes de excees. A exceo mais genrica Exception. A ttulo de exemplo vamos examiar agora os problemas que
podem ocorer na abertura e leitura de um ficheiro.
try {
Scanner input = new Scanner(new FileReader(nomeFicheiro));
// mais instrues aqui
// onde podem ocorer outros erros.
}
catch (Exception e) {
// tratar o erro aqui
}
Este um mau exemplo ! Porque o catch trata qualquer tipo de erro que possa ocorrer no bloco try. Em consequncia no
se pode fazer um tratamento adequado do erro. Primeira concluso: Devemos usar classes de excees especficas ao problema
encontrado. muito raro usar a classe Exception. Outro exemplo :
try {
Scanner input = new Scanner(new FileReader(nomeFicheiro));
int i = input.nextInt();
}
catch (FileNotFoundException e) {
// tratar o erro aqui
}
Neste caso, o catch permite tratar convenientemente o erro que ocorre se o ficheiro no existir mas, outros erros so possveis.
Se o ficheiro estiver vazio, a exceo NoSuchElementException ser lanada; se o ficheiro no contiver um nmero inteiro a exceo
InputMismatchException ser lanada.
Como tratar essas vrias hipteses ?
Primeira tentativa :
try {
Scanner input = new Scanner(new FileReader(nomeFicheiro));
int i = input.nextInt();
}
catch (FileNotFoundException e) {
System.err.println("O ficheiro no existe ....");

}
catch (NoSuchElementException e) {
System.err.println("O ficheiro est vazio !!!");
}
catch (InputMismatchException e) {
System.err.println("O ficheiro no contm um inteiro !!!")
}
Esta soluo tem um problema. Nas instrues try-catch com vrios blocos catch, apenas um destes, no mximo, executado: o primeiro cujo tipo de exceo declarada no incio do bloco catch corresponde ao tipo da exceo que foi lanada no bloco
try. As excees so tratadas na ordem dos blocos catch. Se o ficheiro no contiver um inteiro, vai aparecer no ecr :
O ficheiro est vazio !!!
Porqu ? Vejamos a http://java.sun.com/j2se/1.5.0/docs/api/java/util/InputMismatchException.html. Logo no incio da
pgina v-se a hierarquia das classes. Acima da classe InputMismatchException encontramos a classe NoSuchElementException
acima da qual encontramos a classe RuntimeException e a seguir a classe Exception. Nesta lista Exception a classe a mais
genrica e a classe InputMismatchException a mais especfica.
Para que o programa funcione como esperado, os blocos catch devem ser ordenados do mais especfico at o mais genrico. A
soluo correcta ao problema anterior :
try {
Scanner input = new Scanner(new FileReader(nomeFicheiro));
int i = input.nextInt();
}
catch (FileNotFoundException e) {
System.err.println("O ficheiro no existe ....");
}
catch (InputMismatchException e) {
System.err.println("O ficheiro no contm um inteiro !!!");
}
catch (NoSuchElementException e) {
System.err.println("O ficheiro est vazio !!!");
}
Resumindo: Uma exceo representa uma anomalia na execuo do programa, uma instncia da classe Exception ou de
uma das suas subclasses. A instruo throw usada para lanar uma exceo. Quando ocorre uma anomalia ou um erro, este
deve ser tratado, isto , no mnimo, deve avisar-se o utilizador (se no houver maneira de corrigir o erro automaticamente). Para
esse efeito deve usar-se a instruo try-catch para capturar e tratar uma exceo. Esta instruo composta por um bloco try e
um ou mais blocos catch. No bloco try ficam as instrues que podem causar o erro. usado um bloco catch para cada tipo de
exceo que se quer tratar. A ordem dos blocos catch relevante. Como pode no ser conveniente tratar um erro acrescentando
cdigo junto do stio onde o erro pode ocorrer, possvel delegar o seu tratamento usando a palavra throws na assinatura do
mtodo para anunciar as excees que podem resultar da sua execuo.
H todavia um conjunto de excees que no so verificadas e, portanto, no requerem throws na assinatura dos mtodos onde
podem ser lanadas. o caso, por exemplo, da ArithmeticException .
Para saber mais : pode comear por consultar Java: Software Solutions, Foundations of Program Design. Lewis & Loftus.
Addison-Wesley, cap. 10, ou Objects, Abstraction, Data Structures and Design Using Java, Version 5.0. Koffman e Wolfgang. Wiley &
Sons, seces 2.2 a 2.4.

1. Exerccio
Escreva uma classe fornecedora NiveisExcecao, com trs metodos. Cada mtodo, para alm do que especificamente indicado
em seguida, quando inicia deve escrever no ecr uma mensagem assinalando que entrou no mtodo x e outra antes de terminar
assinalando que vai sair do mtodo x.
void nivel3() - divide um inteiro por 0,
void nivel2() - chama simplesmente o mtodo nivel3,
void nivel1() - chama o mtodo nivel2 num bloco try-catch; no bloco catch deve apanhar uma ArithmeticException,
escrever a mensagem de erro e o contedo da pilha de chamada dos mtodos
Escreva uma classe cliente PropagacaoExcep que assinala o incio e o fim (com mensagens para o ecr) e de entre as duas
mensagens cria um objecto do tipo NiveisExcecao e chama o respectivo mtodo nivel1.
Depois de verificar o funcionamento do programa, altere o mtodo nivel2() para apanhar ArithmeticException. Experimente
outras variantes e verifique as consequncias.
Nota 1: Neste exerccio, excepcionalmente, a classe fornecedora escreve no ecr, para facilitar a didctica de observao do processo
de passagem e processamento de excees.
Nota 2: Consultar a documentao da classe Exception, em particular dos mtodos getMessage e getStackTrace.

Você também pode gostar