• Nenhum resultado encontrado

Sistemas de informa¸c˜ao – Univ´as

N/A
N/A
Protected

Academic year: 2019

Share "Sistemas de informa¸c˜ao – Univ´as"

Copied!
10
0
0

Texto

(1)

Sistemas de informa¸c˜ao – Univ´as

Roberto Ribeiro Rocha

Maio de 2014

Sum´

ario

1 Introdu¸c˜ao 1

2 Problematiza¸c˜ao 1

3 Exce¸c˜oes 1

4 Tratamento de Exce¸c˜oes 3

4.1 Hierarquia das exce¸c˜oes . . . 5

4.2 Delegando exce¸c˜oes . . . 6

4.3 Lan¸cando exce¸c˜oes . . . 7

(2)

1

Introdu¸

ao

Todos os programas est˜ao sujeitos a falhas que podem interromper a execu¸c˜ao e causar perdas para os usu´arios e terceiros. ´E esperado de um sistema que ele seja tolerante a falhas, ou seja, que ele consiga recuperar de poss´ıveis problemas que venha acontecer, dando continuidade `a execu¸c˜ao de suas tarefas.

O desenvolvedor deve ficar atendo `as poss´ıveis falhas no sistema para que elas se-jam tratadas adequadamente, criando estrat´egias de tolerˆancia e corre¸c˜ao destas falhas. A linguagem Java fornece este recurso importante que ´e chamado de tratamento de exce¸c˜oes, que ´e feito atrav´es da manipula¸c˜ao deexce¸c˜oes.

2

Problematiza¸

ao

Utilizando o exemplo da classeConta, o m´etodosacar(...) efetua o saque somente se o saldo for suficiente retornando true indicando sucesso e retorna false caso o saldo seja insuficiente.

Esta abordagem resolve o problema caso n˜ao haja dinheiro suficiente para um saque, por´em o m´etodo que fez esta chamada pode n˜ao verificar o valor retornado e continuar a executar de maneira inconsistente.

Exemplo 1

O c´odigo a seguir permite que o pagamento seja efetuado mesmo que a conta n˜ao tenha saldo para a opera¸c˜ao.

1 Conta conta = new Conta (" Teste ", 1234) ; 2 conta . d e p o s i t a r (100) ;

3 conta . sacar (200) ;

4 r e a l i z a r P a g a m e n t o (200) ;// esta opera c¸ ˜a o ´e i n c o n s i s t e n t e

O m´etodo sacar(...) deve possuir uma forma de avisar o m´etodo que o chamou de forma que o chamador saiba o ocorrido e tome as providˆencias necess´arias para tratar o problema.

O recurso utilizado para notificar que a chamada de um m´etodo n˜ao foi realizada com sucesso ´e chamada deexcec¸˜ao, e seu tratamento normalmente ´e feito pelo m´etodo chamador.

3

Exce¸

oes

Exce¸c˜ao´e um acontecimento de algum evento ou uma situa¸c˜ao que ocorre de ma-neira inesperada no sistema.

Exemplo 2

(3)

1 p a c k a g e br . edu . univas . lab3 . excecao ; 2

3 p u b l i c c l a s s Runner { 4

5 p u b l i c s t a t i c void main ( String [] args ) { 6 ca lcu lar () ;

7 }

8

9 p u b l i c s t a t i c void ca lcu lar () {

10 System . out . println (" I n i c i a n d o ... ") ; 11 int x = 10 , y = 0 , z ;

12 z = x / y ;

13 System . out . println (" R e s u l t a d o : " + z ) ;

14 }

15 }

Ao executar este c´odigo, ele imprimir´a no console o seguinte resultado: Iniciando...

Exception in thread "main"java.lang.ArithmeticException: / by zero at br.edu.univas.lab3.excecao.Runner.calcular(Runner.java:12)

at br.edu.univas.lab3.excecao.Runner.main(Runner.java:6)

Este conjunto de informa¸c˜oes ´e conhecido como stacktrace e s˜ao de extrema im-portˆancia para o programador, pois fornece as informa¸c˜oes sobre a falha ocorrida e sua localiza¸c˜ao.

O funcionamento do esquema de exce¸c˜oes ser´a demostrado baseado no exemplo 2: quando ocorre uma falha (linha 12), uma exce¸c˜ao ´e criada e lan¸cada (ArithmeticException), interrompendo a execu¸c˜ao do m´etodo corrente (calcular(). A interrup¸c˜ao do m´etodo faz com que a execu¸c˜ao do programa volte para o m´etodo chamador (main), fazendo com que ele seja interrompido tamb´em. Esta interrup¸c˜ao vai ocorrendo at´e que o programa termine.

As interrup¸c˜oes ocorrem porque nenhum m´etodo fez a captura (tratamento ade-quado) da exce¸c˜ao, for¸cando o Java imprimir as informa¸c˜oes de origem e tipo da exce¸c˜ao e de todos os m´etodos stack) envolvidos na execu¸c˜ao (stack). A stack armazena as in-forma¸c˜oes(vari´aveis, parˆametros, linha em execu¸c˜ao) de um m´etodo quando este chama outro m´etodo.

Se algum m´etodo da stack possui um tratamento adequado para a exce¸c˜ao, ent˜ao ele captura-a e continua sua execu¸c˜ao normal.

Exemplo 3

Incluir o m´etodo abaixo no c´odigo do Exemplo 3 e substituir a chamada do m´etodo calcular() pelo m´etodoimprimir() nomain.

1 p u b l i c s t a t i c void i m p r i m i r A r r a y () {

2 System . out . println (" I n i c i a n d o impress ˜a o ... ") ; 3 int[] e l e m e n t o s = new int[5];

4 for (int i = 0; i <= 10; i ++) { 5 e l e m e n t o s [ i ] = i ;

6 System . out . println ( i ) ;

7 }

(4)

9 }

O resultado ser´a:

Iniciando impress˜ao... 0

1 2 3 4

Exception in thread "main"java.lang.ArrayIndexOutOfBoundsException: 5 at br.edu.univas.lab3.excecao.Runner.imprimirArray(Runner.java:20) at br.edu.univas.lab3.excecao.Runner.main(Runner.java:6)

Agora, os dados do stacktrace s˜ao diferentes, e relativos ao problema ocorrido.

Exemplo 4

Outro problema muito comum ´e o acesso `a referˆencias de objeto null, conforme mostrado seguir:

1 p u b l i c s t a t i c void i m p r i m i r S a l d o () {

2 System . out . println (" I m p r i m i n d o saldo ... ") ; 3 Conta conta = null;

4 System . out . println (" Saldo : " + conta . get Sal do () ) ; 5 System . out . println (" Fim da impress ˜a o . ") ;

6 }

Se o main chamar este m´etodo, o resultado no console ser´a: Imprimindo saldo...

Exception in thread "main"java.lang.NullPointerException

at br.edu.univas.lab3.excecao.Runner.imprimirSaldo(Runner.java:35) at br.edu.univas.lab3.excecao.Runner.main(Runner.java:6)

Para que o programa n˜ao seja interrompido, ´e necess´ario fazer o tratamento de exce¸c˜oes adequadamente.

4

Tratamento de Exce¸

oes

Otratamento de exce¸c˜oespermite controlar falhas, tratando-as adequadamente, tomando as decis˜oes necess´arias para a continua¸c˜ao da execu¸c˜ao normal do sistema. Este controle ´e feito atrav´es da manipula¸c˜ao de exce¸c˜oes.

Quando ocorre uma falha, o programa cria e lan¸ca (throw) uma exce¸c˜ao. Esta exce¸c˜ao pode ser capturada (catch) por qualquer m´etodo interessado e tratada de forma que a execu¸c˜ao normal do c´odigo torne-se v´alida novamente.

O tratamento de exce¸c˜oes ´e feita utilizando uma estrutura fornecida pela linguagem, composta por trˆes comandos:

(5)

uma poss´ıvel exce¸c˜ao. Ele ´e usado quando o programador sabe que um determinado conjunto de instru¸c˜oes pode gerar algum tipo de exce¸c˜ao.

catch: ´e o bloco de comandos que ´e executado caso a exce¸c˜ao capturada (especifi-cada pelo catch) foi lan¸cada dentro do bloco try. O bloco catch ´e opcional, mas ele normalmente ´e implementado junto a um bloco try. O bloco catch pode ser definido v´arias vezes, cada um com uma exce¸c˜ao diferente, cada um tratando um tipo diferentes de falha ocorrida.

finally: ´e o bloco de comandos de instru¸c˜oes que sempre ser´a executado ao final de um bloco try-catch, independente do que ocorreu nos blocos anteriores. Ele nor-malmente ´e utilizado para fazer algum processamento de finaliza¸c˜ao (fechar conex˜ao, liberar recursos, salvar informa¸c˜oes, etc.). O bloco finally tamb´em ´e opcional.

A l´ogica de execu¸c˜ao destes trˆes blocos ´e a seguinte:

• Tenta executar os comandos do bloco try;

• Se algum comando do try gerar uma exce¸c˜ao, ent˜ao executa os comandos do bloco catch apropriado. O desenvolvedor deve ter o cuidado para que o blococatch n˜ao gere uma exce¸c˜ao.

• Independente do que foi executado dentro dotrye docatche das exce¸c˜oes geradas, os comandos do bloco finally sempre ser˜ao executados.

Exemplo 5

O c´odigo do Exemplo 2, poderia evitar a interrup¸c˜ao do programa tratando adequa-damente a exce¸c˜ao ArithmeticException da seguinte maneira:

1 p u b l i c s t a t i c void ca lcu lar () {

2 System . out . println (" I n i c i a n d o c ´a lculo ... ") ; 3 int x = 10 , y = 0 , z ;

4 try {

5 z = x / y ;

6 System . out . println (" R e s u l t a d o : " + z ) ; 7 } c a t c h ( A r i t h m e t i c E x c e p t i o n e ) {

8 System . out . println (" Erro no c ´a lculo : " + e ) ; 9 } f i n a l l y {

10 System . out . println (" Fim do c ´a lculo . ") ;

11 }

12 }

Neste caso, o c´odigo dentro do bloco try ´e monitorado e, se ocorrer a exce¸c˜ao do tipo ArithmeticException, o bloco catch ´e executado. O bloco finally sempre ser´a executado e o resultado da execu¸c˜ao ´e a seguinte:

Iniciando c´alculo...

(6)

A vari´aveleespecificada pelocatchcorresponde ao objeto da classeArithmeticException correspondente `a exce¸c˜ao capturada. Como qualquer outro objeto ele pode ser utilizado

pelo programador da forma que desejar.

Exemplo 6

Neste exemplo, ser´a mostrado o uso de mais de um blococatchpara tratar diferentes tipos de exce¸c˜oes.

1 p u b l i c s t a t i c void ca lcu lar () {

2 System . out . println (" I n i c i a n d o c ´a lculo ... ") ; 3 int x = 10 , y = 0 , z ;

4 try {

5 z = x / y ;

6 System . out . println (" R e s u l t a d o : " + z ) ; 7 } c a t c h ( A r i t h m e t i c E x c e p t i o n e ) {

8 System . out . println (" Erro no c ´a lculo : " + e ) ; 9 } c a t c h ( C l a s s C a s t E x c e p t i o n e ) {

10 System . out . println (" Erro no c ´a lculo : " + e ) ; 11 } f i n a l l y {

12 System . out . println (" Fim do c ´a lculo . ") ;

13 }

14 }

Em v´arios casos, as exce¸c˜oes comoArithmeticException,NullPointerException, ArrayIndexOutOfBoundsException e outras podem ser evitadas pelo programador fa-zendo valida¸c˜oes no c´odigo. Logo, nestes casos ´e melhor tratar o problema antes dele acontecer. No caso do Exemplo 6, uma solu¸c˜ao seria verificar se o denominador ´e dife-rente de zero, assim:

1 p u b l i c s t a t i c void ca lcu lar () {

2 System . out . println (" I n i c i a n d o c ´a lculo ... ") ; 3 int x = 10 , y = 0 , z ;

4 if( y != 0) { 5 z = x / y ;

6 System . out . println (" R e s u l t a d o : " + z ) ;

7 } else {

8 System . out . println (" Erro ao efetuar o c ´a lculo : divis ˜a o por zero . ") ;

9 }

10 System . out . println (" Fim do c ´a lculo . ") ;

11 }

4.1

Hierarquia das exce¸

oes

No Exemplo 6, o bloco catch faz a captura de exce¸c˜oes que s˜ao objetos da classe ArithmeticException. Todas as exce¸c˜oes do Java s˜ao objetos que pertencem `a uma hie-rarquia de classes, que est´a representada parcialmente na Figura 1, contendo as principais classes de exce¸c˜oes:

Esta hierarquia divide as exce¸c˜oes em diferentes tipos:

(7)

Figura 1: Hierarquia das Exce¸c˜oes.

Exemplo: falta de mem´oria. Normalmente n˜ao ´e previsto a recupera¸c˜ao deste tipo de falha, embora seja poss´ıvel.

RuntimeException: ´e usado para indicar condi¸c˜oes que n˜ao foram definidas no projeto de um sistema. Por este motivo o compilador n˜ao obriga que elas sejam tratadas, pois s˜ao geradas somente em tempo de execu¸c˜ao.

Exception: s˜ao erros previs´ıveis. Estas exce¸c˜oes obrigam o m´etodo chamador a trat´a-las. Caso elas n˜ao forem tratadas, o compilador ir´a acusar um erro de compila¸c˜ao.

O tratamento de todas as exce¸c˜oes poss´ıveis torna o sistema robusto, por´em esta ´e uma tarefa dif´ıcil de fazer e nem sempre ´e vi´avel. O desenvolvedor deve ficar atento para perceber onde o tratamento de exce¸c˜oes deve ser mais rigoroso, a fim de encontrar um equil´ıbrio entre qualidade e volume de c´odigo.

Importante: quando um bloco catch for definido para tratar uma exce¸c˜ao, este mesmo catch pode tratar todas as exce¸c˜oes que s˜ao de classes filhas a partir da classe definida. Aqui tamb´em vale a regra do polimorfismo. Onde cabe uma m˜ae cabe uma filha. Para tratar exce¸c˜oes filhas separadamente das m˜aes, ´e necess´ario colocar blocos catch distintos para cada uma delas, sendo que as filhas devem vir antes (acima) das m˜aes.

4.2

Delegando exce¸

oes

(8)

seja, o m´etodo repassa a exce¸c˜ao para o m´etodo que o chamou, deixando para o chamador a responsabilidade de tratar a exce¸c˜ao. Esta forma tamb´em ´e chamada de tratamento pendente de exce¸c˜oes.

Esta t´ecnica deve ser utilizada somente nos casos que fazem sentido repassar a exce¸c˜ao. Isto deve ser definido a n´ıvel de projeto e n˜ao h´a regras para seu uso.

Em Java, essa pendˆencia do tratamento de uma exce¸c˜ao ´e definida pela palavra reservadathrows, mostrada no pr´oximo exemplo.

Exemplo 7

O m´etodo imprimir(...) poderia delegar a exce¸c˜ao para seu chamador ao inv´es de trat´a-la dentro de seu pr´oprio corpo, da seguinte maneira:

1 p u b l i c s t a t i c void i m p r i m i r A r r a y () t h r o w s A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n

{

2 System . out . println (" I n i c i a n d o impress ˜a o ... ") ; 3 int[] e l e m e n t o s = new int[10];

4 for (int i = 0; i <= 15; i ++) { 5 e l e m e n t o s [ i ] = i ;

6 System . out . println ( i ) ;

7 }

8 System . out . println (" Fim da impress ˜a o . ") ;

9 }

Neste caso, o m´etodo preocupa somente com a l´ogica de neg´ocio, deixando o c´odigo mais limpo e claro. Enquanto que o m´etodo chamador deve tratar a exce¸c˜ao lan¸cada por este m´etodo.

´

E importante lembrar que quando uma exce¸c˜ao for gerada, a execu¸c˜ao c´odigo ser´a interrompida, mesmo se houver a pendˆencia do tratamento da exce¸c˜ao.

Exce¸c˜oes filhas de RuntimeException n˜ao necessitam ser declaradas para serem delegadas.

Caso for necess´ario o m´etodo declarar que ele pode lan¸car mais de uma exce¸c˜ao, elas devem ser separadas por v´ırgula depois dothrows.

Outra estrat´egia que pode ser utilizada ´e: o m´etodo trata algumas exce¸c˜oes e lan¸ca outras.

4.3

Lan¸

cando exce¸

oes

Em v´arios casos, o programador pode optar por “for¸car” o lan¸camento de uma exce¸c˜ao. Estes lan¸camentos s˜ao previamente conhecidos e deve ser feita dentro de m´etodos definidos com tratamento de exce¸c˜oes pendentes.

Com isso, quem chamar este m´etodo j´a sabe que existe exer¸c˜oes a serem tratadas e deve fornecer os recursos para isto, fazendo com que o chamador fique sabendo o que ocorreu, sem a necessidade de validar valores de retorno.

(9)

Exemplo 8

Voltando no m´etodosacar(...) da conta, ele ficaria da seguinte maneira:

1 p u b l i c void sacar (f l o a t valor ) { 2 if (this. saldo < valor ) {

3 I l l e g a l A r g u m e n t E x c e p t i o n e ;

4 e = new I l l e g a l A r g u m e n t E x c e p t i o n () ; 5 t h r o w e ;

6 } else {

7 this. saldo -= valor ;

8 }

9 }

Na linha 5 a exce¸c˜ao ´e lan¸cada. A execu¸c˜ao deste m´etodo ´e interrompida e o m´etodo chamador recebe a exce¸c˜ao instanciada aqui.

Para melhorar o programa, pode-se instanciar a exce¸c˜ao utilizando outros constru-tores, por exemplo indicando qual ´e a descri¸c˜ao/motivo da exce¸c˜ao. Um exemplo seria assim:

1 I l l e g a l A r g u m e n t E x c e p t i o n e = new I l l e g a l A r g u m e n t E x c e p t i o n (" Saldo

i n s u f i c i e n t e ! ") ;

No m´etodo chamador, ele trata a exce¸c˜ao e pode imprimir o conte´udo da mensagem:

1 Conta conta = new Conta (" Teste ", 1234) ; 2 conta . de pos ita (100) ;

3 try {

4 conta . sacar (200) ;

5 System . out . println (" Saque com sucesso ") ; 6 } c a t c h ( I l l e g a l A r g u m e n t E x c e p t i o n e ) { 7 System . out . println ( e . g e t M e s s a g e () ) ;

8 }

Transportando informa¸

oes em uma exce¸

ao

Os construtores das exce¸c˜oes Java normalmente aceitam umaString, um objeto de outra exce¸c˜ao ou ambos. Estas informa¸c˜oes s˜ao definidas quando um objeto de exce¸c˜ao ´e criado. Como as exce¸c˜oes podem ser repassadas para os m´etodos chamadores, elas podem carregar estas informa¸c˜oes atrav´es de toda a pilha de m´etodos at´e chegar de volta ao main.

Isto permite que se saiba, por exemplo nomain, qual ´e a descri¸c˜ao do erro, utilizando o m´etodo getMessage() da exce¸c˜ao ou qual ´e a exce¸c˜ao que causou esta, atrav´es do m´etodoe.getCause().

4.4

Exce¸

oes criadas pelo programador

(10)

permite que a exce¸c˜ao contenha valores espec´ıficos necess´arios que podem ser transporta-dos sendo ´uteis em v´arios cen´arios.

Para criar sua pr´opria exce¸c˜ao, basta criar uma classe que seja filha da classe Throwable, ou seja, herde de qualquer uma das classes de exce¸c˜oes j´a existentes. As-sim pode-se criar uma classe para indicar o saldo insuficiente da conta.

1 p u b l i c c l a s s S a l d o I n s u f i c i e n t e E x c e p t i o n e x t e n d s E x c e p t i o n { 2

3 p u b l i c S a l d o I n s u f i c i e n t e E x c e p t i o n ( String men sag em ) { 4 s u p e r( me nsa gem ) ;

5 }

6 }

Para utilizar esta classe, ´e necess´ario alterar o m´etodo sacar(...) para delegar e lan¸car a exce¸c˜ao.

1 p u b l i c void sacar (f l o a t valor ) t h r o w s S a l d o I n s u f i c i e n t e E x c e p t i o n { 2 if (this. saldo < valor ) {

3 t h r o w new S a l d o I n s u f i c i e n t e E x c e p t i o n (" Saldo i n s u f i c i e n t e para sacar

" + valor ) ;

4 } else {

5 this. saldo -= valor ;

6 }

7 }

E o m´etodo que usa a conta necessita tratar a exce¸c˜aoSaldoInsuficienteException apropriadamente:

1 Conta conta = new Conta (" Teste ", 1234) ; 2 conta . de pos ita (100) ;

3 try {

4 conta . sacar (200) ;

5 System . out . println (" Saque com sucesso ") ; 6 } c a t c h ( S a l d o I n s u f i c i e n t e E x c e p t i o n e ) { 7 System . out . println ( e . g e t M e s s a g e () ) ;

8 }

Observa¸c˜ao importante: N˜ao deixar o bloco do catch vazio!!!

Exerc´ıcio 1 –

Utilizando o c´odigo da classe

Conta

fazer as seguintes

altera¸c˜oes:

1. Alterar o c´odigo de acordo com as ´ultimas 3 listagens.

2. Alterar o m´etodo transferirPara(...) para suportar as altera¸c˜oes.

3. Criar uma classe chamada ValorInvalidoException para validar os valores de saque, dep´osito e transferˆencia. O valor aceito deve ser maior que 0 e menor que 1000, caso contr´ario, os m´etodos devem lan¸car esta exce¸c˜ao.

Imagem

Figura 1: Hierarquia das Exce¸c˜oes.

Referências

Documentos relacionados

Daclatasvir combined with sofosbuvir or simeprevir in liver transplant recipients with severe recurrent hepatitis C infection. • Efficacy and safety data for daclatasvir-based

Com isso, alguns objetivo foram tra¸ cados tais como: o estudo te´ orico e a implementa¸ c˜ ao num´ erica de m´ etodos aplicados ` a resolu¸ c˜ ao de Sistemas de Equa¸ c˜ oes n˜

Resumo: Neste texto s˜ao apresentadas algumas propostas de marcos significativos cujo objectivo ´e provar, sem margem para d´ uvidas, que a actividade matem´atica na Universidade

Demonstra¸c˜ao. Designamos esse tipo de ponto fixo de n´o repulsivo. Analogamente, se a derivada da fun¸c˜ao F tiver o valor entre 0 e 1, as sequˆencias que come¸carem

rgeom(n, p) distribui¸ c˜ ao Geom´ etrica(p) runif(n, a, b) distribui¸ c˜ ao Uniforme(a,b) rexp(n, lambda) distribui¸ c˜ ao Exponencial(lambda) rnorm(n, mean, sd) distribui¸ c˜

Sob a perspectiva da arquitetura geral, o presente sistema pode ser visto como uma cole¸c˜ ao interativa de CRUDs 6. As exce¸c˜ oes ficam por conta da execu¸c˜ ao inte- rativa

– exce¸c˜ ao temporal de inicializa¸c˜ ao para uso de valor default: ´ e levantada quando a exce¸c˜ ao temporal de inicializa¸c˜ ao n˜ ao pode ser tratada e uma vez que o

Quando os arquivos de objeto são combinados, o endereço relativo original de fnc1 (mostrado como 0x0100 :) é alterado para seu endereço final no arquivo executável (mostrado como