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