Paradigmas de Linguagens de Programação - Tratamento de Exceções

Preview:

Citation preview

Prof. Adriano Teixeira de Souza

Sistemas de tratamento de exceções Exceções em Java

Componentes podem ter problemas durante a execução e reagir como: ◦ terminar o programa; ◦ retornar um valor de erro indicando falha; ◦ retornar e ignorar o problema; ◦ chamar uma função para tratar o erro, etc...

Problemas: erros e exceções ◦ representam situações anormais (exceções) ou inválidas

(erros) durante o processo de execução

Componentes robustos: tentam sanar os problemas

Prof. Adriano Teixeira de Souza

Os problemas comuns de execução: ◦ falha na aquisição de um recurso (new, open..) ◦ tentativa de fazer algo impossível (divisão por zero,

índice inválido..) ◦ outras condições inválidas (lista vazia, overflow..)

objeto.metodo() método() dados

classe

Prof. Adriano Teixeira de Souza

Premissas: ◦ Possíveis problemas de execução de um método podem

ser antecipados pelo programador ◦ Situações de erro podem ser revertidas

Solução ideal ◦ tratamento de problemas separado do código normal ◦ Mecanismo: sistemas de tratamento de exceções (STE)

Prof. Adriano Teixeira de Souza

Mecanismos oferecidos pela LP

Um STE deve ser capaz de : ◦ detectar a ocorrência de uma situação anormal de

processamento

◦ identificar o tipo de ocorrência e enviar um sinal ao programa (disparar uma exceção)

◦ capturar a exceção em algum ponto do programa

◦ tratar uma exceção em algum ponto do programa (ativar tratador)

disparar detectar capturar tratar

Prof. Adriano Teixeira de Souza

Exceções podem ser disparadas de duas maneiras: ◦ Implicitamente, pelo ambiente operacional

o ambiente de execução não consegue executar um comando em um programa

◦ Explicitamente, pelo programa uma função do programa não consegue prosseguir a

execução

disparar detectar capturar tratar

Prof. Adriano Teixeira de Souza

public class Zero {

public static void main ( String[] args){

int numerador = 10;

int denominador = 0;

System.out.println(numerador/denominador);

} // main

} // Zero mensagem

do JRE

execução: java.lang.ArithmeticException: / by zero at Zero.main(Zero.java:xx)

xx: número da linha do arquivo fonte onde ocorreu o erro

Prof. Adriano Teixeira de Souza

comandos que podem disparar exceções

disparar detectar capturar tratar

Indicação da região do programa que deve ser monitorada pelo sistema de tratamento de exceções

Sintaxe: try {<bloco de comandos>}

Exemplo:

try { num= Integer.parseInt(stdin.readLine()); valido = true; }

Prof. Adriano Teixeira de Souza

Um comando catch tem as seguintes funções:

capturar um (determinado) tipo de exceção

implementar um tratador para aquele tipo de exceção

Sintaxe: catch(<tipo><arg>){<comandos>}

Exemplo:

catch (NumberFormatException exc) { System.out.println(“Entrada invalida. Digite outra”); }

disparar detectar capturar tratar

Prof. Adriano Teixeira de Souza

try {

num= Integer.parseInt(stdin.readLine());

valido = true;

}

catch (NumberFormatException exc) {

System.out.println(“Entrada invalida. Digite outra”);

}

catch (IOException exc) {

System.out.println(“Problema de entrada. Terminando!”);

System.exit(0);

}

Prof. Adriano Teixeira de Souza

Exceções são objetos, instâncias de alguma sub-classe de java.lang.Throwable ◦ podem conter dados ◦ podem definir métodos

Um dos dados é um String inicializado em tempo de criação do objeto, consultado por ◦ Throwable.getMessage()

Throwable tem duas sub-classes: Error e Exception. ◦ Exceptions: podem ser capturadas e tratadas ◦ Errors: correspondem a problemas mais graves, que não

podem ser recuperados

Prof. Adriano Teixeira de Souza

Instâncias da classe Error e suas extensões ◦ correspondem a problemas mais graves ocorridos no

ambiente de execução ◦ conhecidas como exceções não-verificadas

Instâncias da classe Exception e suas extensões ◦ podem ser tratadas localmente ◦ conhecidas como exceções verificadas: o compilador

“verifica” antes da execução do programa ◦ comandos que disparam exceções verificadas devem ser

colocados em um bloco try

Prof. Adriano Teixeira de Souza

Exception: hierarquia de exceções

Exception java.lang

IOException java.io

Runtime Exception

NumberFormat Exception

contexto: java.lang.Object |

java.lang.Throwable | java.lang.Exception

Prof. Adriano Teixeira de Souza

unidade de chamada

unidade de execução

tratador de exceção

Tratar exceções cria um fluxo de controle separado do fluxo normal de execução

Abordagens: ◦ tratar a exceção onde ela ocorre ( local) ◦ tratar a exceção em outro ponto do programa

Prof. Adriano Teixeira de Souza

comando anterior;

try {

num= Integer.parseInt(stdin.readLine());

valido = true;

}

catch (NumberFormatException exc) {

System.out.println(“Entrada invalida. Digite outra”);

}

catch (IOException exc) {

System.out.println(“Problema de entrada. Terminando!”);

System.exit(0);

}

comando posterior;

Prof. Adriano Teixeira de Souza

comando anterior;

try {

num= Integer.parseInt(stdin.readLine());

valido = true;

}

catch (NumberFormatException exc) {

System.out.println(“Entrada invalida. Digite outra”);

}

catch (IOException exc) {

System.out.println(“Problema de entrada. Terminando!”);

System.exit(0);

}

comando posterior;

OU

Prof. Adriano Teixeira de Souza

• Modelos de implementação

Término: após a execução do tratador de exceção,

a unidade onde ocorreu o erro é terminada

Continuação: após a execução do tratador de exceção,

a unidade continua a sua execução

objeto.metodo() método()

dados

chamada execução

Prof. Adriano Teixeira de Souza

tratador local tratador no requisitante

Hipótese 1:

- B acusa erro e termina a

execução

- A captura o erro e trata a

exceção

Hipótese 2:

- B faz tratamento local

de erro

- Caso não consiga recuperar

o erro, recai na Hipótese 1

objeto.metodo() método()

dados

A: chamada B: execução

Prof. Adriano Teixeira de Souza

Para buscar o tratador de exceção: ◦ percorre a ‘cadeia’ de ativações, a partir do ambiente

local (pilha de execução)

◦ durante o caminho, são destruídos os objetos criados nos ambientes percorridos (retira da pilha de execução)

◦ se não for encontrado um tratador a exceção a exceção chega ao método main, que termina o programa

main()

m1()

m2()

Ver: método printStackTrace()

Prof. Adriano Teixeira de Souza

Sinal emitido pelo programa com a indicação da ocorrência de uma exceção ◦ if (…problema…)

throw new IOException( );

Instanciação a partir de uma classe ◦ throw new <classe()> ◦ Exemplo: if (t==null) throw new NullPointerException();

Objeto já instanciado ◦ throw <objeto>

◦ Exception problema = new Exception (“Alerta!”);

◦ Exemplo:.... throw problema; ...

Prof. Adriano Teixeira de Souza

Considerando que: ◦ a unidade de execução pode detectar problemas mas

geralmente não sabe como tratá-lo ◦ a unidade requisitante não pode detectar problemas

mas geralmente sabe como tratá-los ◦ é conveniente saber quais são as exceções que um

método pode disparar para providenciar um tratador

Cláusula throws : usada no cabeçalho de um método para indicar que ele propaga a exceção

Exemplo: ◦ public Integer(String s) throws NumberFormatException

Prof. Adriano Teixeira de Souza

Para forçar a ocorrência de uma exceção, utiliza-se a palavra reservada throw (no singular)

public void metodo1( ) {

try {

metodo2( );

} catch (IOException e) { System.err.println(e); }

}

public void metodo2( ) throws IOException {

if (…problema…)

throw new IOException( );

}

throws (plural) propaga exceção

import java.io.*;

public class simplesIO {

static BufferedReader stdin=new BufferedReader

(new InputStreamReader(System.in));

public static void saida(String ms){

System.out.print (ms);

}

public static String entrada() throws IOException{

return stdin.readLine();

}

public static void linha(){

System.out.println();

}

}//simplesIO

// exemplo de chamada:

try{linha=entrada();}

catch(IOException e){}

public String readLine() throws IOException

Prof. Adriano Teixeira de Souza

import java.io.*;

public class simplesIO {

static BufferedReader stdin=new BufferedReader

(new InputStreamReader(System.in));

public static void saida(String ms){

System.out.print (ms);}

public static String entrada(){

try { String lin= stdin.readLine();

return lin;

} catch(IOException){// tratar aqui}

}

public static void linha(){

System.out.println();

}

}//simplesIO

// exemplo de chamada:

linha=entrada();

Prof. Adriano Teixeira de Souza

Exceções definidas pelo usuário

Exception java.lang

IOException java.io

RunTime Exception

NumberFormat Exception

Minha Exception

Prof. Adriano Teixeira de Souza

// dispara e propaga exceção

void metodo() throws TempExc {

throw new TempExc();

}

// definição da exceção

class TempExc extends Exception{

public TempExc () { super(); } // executa Exception()

public TempExc (String s) {System.out.println(s + "\n");}

}

try{ metodo();}

catch(TempExc e){

}

Prof. Adriano Teixeira de Souza

try { .... }

catch (Tipo1 exc) { .....}

catch (Tipo2 exc) {......}

finally {<bloco de comandos>} A cláusula finally ◦ é utilizada para forçar a execução de um bloco de

código ◦ associada a um bloco try ◦ pode ser utilizada com ou sem o bloco catch

A cláusula finally é executada nas seguintes condições: ◦ fim normal do método ◦ devido a uma instrução return ou break ◦ caso uma exceção tenha sido gerada

Prof. Adriano Teixeira de Souza

Dado o seguinte enunciado: Escreva um programa em JAVA que recebe dois strings, S1 e S2 e um número N pela linha de comando e imprima:

◦ Os N primeiros caracteres do String S1 separados por um “-”;

◦ Os N primeiros caracteres do String S1 de traz para diante;

◦ Os N primeiros caracteres do String S2 separados por um “-”;

◦ Os N primeiros caracteres do String S2 de traz para diante.

Prof. Adriano Teixeira de Souza

public class TestaExceptions{

static public void main(String args[]){

String s1,s2;

int n;

s1 = args[0];

s2 = args[1];

n = Integer.parseInt(args[2]);

ImpString.impSep(s1,n);

ImpString.impInv(s1,n);

ImpString.impSep(s2,n);

ImpString.impInv(s2,n);

}

}

class ImpString {

public static void impSep(String str,int n){

String aux = "";

for(int i=0; i<n; i++){

aux = aux + str.charAt(i);

if (i < n-1) aux = aux + '-';

}

System.out.println(aux);

}

public static void impInv(String str,int n){

String aux = "";

for(int i=n-1; i>=0; i--)

aux = aux + str.charAt(i);

System.out.println(aux);

} }

Prof. Adriano Teixeira de Souza

A solução anterior está correta se: ◦ O usuário informar os 3 parâmetros na linha de

comando;

◦ O terceiro parâmetro for um número;

◦ O valor de N for menor ou igual ao comprimento dos strings informados;

O tratamento de situações de erro é fundamental em aplicações reais !

Prof. Adriano Teixeira de Souza

Exemplo:

Entrada: Teste exceções 4 Saída: T-e-s-t tseT e-x-c-e ecxe

Entrada: Teste exceções 10 Saída: java.lang.StringIndexOutOfBoundsException: String index out of range: 5

Entrada: Teste Teste Teste Saída: java.lang.NumberFormatException: Teste

Entrada: Teste Saída: java.lang.StringIndexOutOfBoundsException: 1

Prof. Adriano Teixeira de Souza

public class TestaExceptions{ static public boolean intOk(String s){ for(int i=0; i<s.length(); i++) if (Character.isDigit(s.charAt(i)) == false) return(false); return(true); } public static void main(String args[]){ String s1,s2; int n; if (args.length != 3){ System.out.println("Sintaxe: <string> <string> <int>"); System.exit(0); } if (intOk(args[2]) == false){ System.out.println("O terceiro parâmetro deve ser um inteiro"); System.exit(0); }

(continua...)

Código normal entrelaçado com código excepcional: acrescentou 14 linhas executáveis

Prof. Adriano Teixeira de Souza

(...continua) s1 = args[0]; s2 = args[1]; n = Integer.parseInt(args[2]);

if (n < s1.length()){

ImpString.impSep(s1,n);

ImpString.impInv(s1,n);

}

else System.out.println("O valor de n é maior que o tamanho de S1");

if (n < s2.length()){

ImpString.impSep(s2,n);

ImpString.impInv(s2,n);

}

else System.out.println("O valor de n é maior que o tamanho de S2");

}

}

Prof. Adriano Teixeira de Souza

public class TestaExceptions{

static public void main(String args[]){

String s1="";

String s2="";

int n=0;

try{

s1 = args[0];

s2 = args[1];

n = Integer.parseInt(args[2]);

}

catch(Exception e){

System.out.println("Sintaxe: <string> <string> <int>");

System.exit(0);

}

try{

ImpString.impSep(s1,n);

ImpString.impInv(s1,n);

ImpString.impSep(s2,n);

ImpString.impInv(s2,n);

}

catch(Exception e){

System.out.println("O valor de N é

maior que S1 ou S2");

System.exit(0);

}

}

}

Prof. Adriano Teixeira de Souza

public class TestaExceptions{

static public void main(String

args[]){

String s1="";

String s2="";

int n=0;

try{

s1 = args[0];

s2 = args[1];

n = Integer.parseInt(args[2]);

ImpString.impSep(s1,n);

ImpString.impInv(s1,n);

ImpString.impSep(s2,n);

ImpString.impInv(s2,n);

}

catch(NumberFormatException e){

System.out.println("O terceiro argumento deve

ser um int");

} catch(IndexOutOfBoundsException e){

System.out.println("Sintaxe: <string> <string>

<int>");

} catch (Exception e){

System.out.println("O valor de N é maior que S1

ou S2");

}finally{

System.out.println(”Sempre passa por aqui !!"); }

}

}

Prof. Adriano Teixeira de Souza

class MinhaExcecao extends Exception{

private int val;

public MinhaExcecao(int n){

super("Minha excecao: valor de val="+n);

val = n;

}

public int getVal(){ return(val); }

}

class ImpString {

public static void impSep(String str,int n) throws MinhaExcecao{

String aux = "";

if (n == 0) throw(new MinhaExcecao(n));

for(int i=0; i<n; i++){

aux = aux + str.charAt(i);

if (i < n-1) aux = aux + '-';

}

System.out.println(aux);

}

(continua...)

Prof. Adriano Teixeira de Souza

public static void impInv(String str,int n){

String aux = "";

for(int i=n-1; i>=0; i--)

aux = aux + str.charAt(i);

System.out.println(aux);

} }

public class TestaExceptions{

static public void main(String args[]){

String s1="";

String s2="";

int n=0;

try{

s1 = args[0];

s2 = args[1];

n = Integer.parseInt(args[2]);

ImpString.impSep(s1,n);

ImpString.impInv(s1,n);

ImpString.impSep(s2,n);

ImpString.impInv(s2,n);

} (continua...)

Prof. Adriano Teixeira de Souza

(...continua)

catch(NumberFormatException e){

System.out.println("O terceiro argumento deve ser um int");

}

catch(IndexOutOfBoundsException e){

System.out.println("Sintaxe: <string> <string> <int>");

}

catch(MinhaExcecao e){

System.out.println(e.getMessage());

int x = e.getVal();

}

catch(Exception e){

System.out.println("O valor de N é maior que S1 ou S2");

}

finally{

System.out.println("É obrigado a passar por aqui");

} } }

Prof. Adriano Teixeira de Souza

Recommended