Download - Excepções no Java

Transcript
  • Laboratrios de ProgramaoIntroduo s excees em JavaMarch, 23 2011, 15:59

    Thibault LangloisUma exceo assinala a ocorrncia de uma situao especial, normalmente uma situao de erro, num programa Java. Quandouma 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 blocoscatch. Mais precisamente, no bloco try encontram-se as instrues do programa que so susceptiveis de provocar um erro. Obloco 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 quedesignamos informalmente por tratar a exceo. Os dois tipos de blocos so indissociveis, i.e. no podemos usar um bloco catchsem 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, olanamento de uma exceo da classe Exception feito dentro do bloco try usando explicitamente a instruo throw. Assim quea exceo lanada, o bloco try termina e o bloco catch que tem capacidade para tratar excees daquele tipo, apanha a exceoe 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, oprograma 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, IOExceptione 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 apalavra throws (notar o s no final da palavra) seguida dos nomes das excees lanadas e no tratadas. Quando o mtodo lanauma exceo a sua execuo termina de imediato.

    public void MyMethod(int n) throws IOException, MyExceptionClass//esta ltima uma classe definida pelo programador{

    .

    .

    .}

    1

  • 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 asexcees 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 classeFileInputStream, 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}

    ou2) 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 portantovrias classes de excees. A exceo mais genrica Exception. A ttulo de exemplo vamos examiar agora os problemas quepodem 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 nose pode fazer um tratamento adequado do erro. Primeira concluso: Devemos usar classes de excees especficas ao problemaencontrado. 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 exceoInputMismatchException 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 ....");

    2

  • }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, execu-tado: o primeiro cujo tipo de exceo declarada no incio do bloco catch corresponde ao tipo da exceo que foi lanada no blocotry. 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 dapgina v-se a hierarquia das classes. Acima da classe InputMismatchException encontramos a classe NoSuchElementExceptionacima da qual encontramos a classe RuntimeException e a seguir a classe Exception. Nesta lista Exception a classe a maisgenrica 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. Asoluo 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 deuma das suas subclasses. A instruo throw usada para lanar uma exceo. Quando ocorre uma anomalia ou um erro, estedeve ser tratado, isto , no mnimo, deve avisar-se o utilizador (se no houver maneira de corrigir o erro automaticamente). Paraesse efeito deve usar-se a instruo try-catch para capturar e tratar uma exceo. Esta instruo composta por um bloco try eum ou mais blocos catch. No bloco try ficam as instrues que podem causar o erro. usado um bloco catch para cada tipo deexceo que se quer tratar. A ordem dos blocos catch relevante. Como pode no ser conveniente tratar um erro acrescentandocdigo junto do stio onde o erro pode ocorrer, possvel delegar o seu tratamento usando a palavra throws na assinatura domtodo 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 ondepodem 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. ExerccioEscreva uma classe fornecedora NiveisExcecao, com trs metodos. Cada mtodo, para alm do que especificamente indicadoem seguida, quando inicia deve escrever no ecr uma mensagem assinalando que entrou no mtodo x e outra antes de terminarassinalando 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 duasmensagens 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. Experimenteoutras variantes e verifique as consequncias.Nota 1: Neste exerccio, excepcionalmente, a classe fornecedora escreve no ecr, para facilitar a didctica de observao do processode passagem e processamento de excees.Nota 2: Consultar a documentao da classe Exception, em particular dos mtodos getMessage e getStackTrace.

    3


Top Related