Mecanismo de exceções em Java (POO) Centro de Cálculo Instituto Superior de Engenharia de Lisboa Pedro Alexandre Pereira (palex@cc.isel.ipl.pt)
Conceito de exceção Erro de execução provocado por condição excecional: Indexação fora dos limites num array Utilização de uma referência a null Conversão de tipo de um objeto não permitida Escrever informação num ficheiro só com permissões de leitura A condição excecional pode ter origem: Erros de programação para corrigir Entrada incorreta de dados Utilizador, ficheiros, comunicações Problemas de comunicação Rede, impressora, USB Limitações físicas Disco cheio, falha de alimentação, avaria de hardware Impossível prever todas as situações 2
Captura de exceções try catch finally Bloco try Código que pode lançar exceções Algoritmo pretendido Cláusulas catch Código de tratamento da exceção Várias desde a exceção mais específica até à mais abrangente Bloco finally Código a executado haja ou não qualquer exceção Opcional Liberta recursos pedidos no try Scanner in = null; Pode lançar try { InputMismatch in = new Scanner(System.in); int value = in.nextint(); System.out.println(100/value); Pode lançar Arithmetic catch(inputmismatchexception ex) { System.out.println( "Erro ao ler valor"); catch(arithmeticexception ex) { System.out.println( "Erro de cálculo: " + ex.getmessage()); finally { if (in!=null) in.close(); 3
Captura e recuperação Scanner in = new Scanner(System.in); boolean success = false; do { try { System.out.print("Valor? "); int value = in.nextint(); System.out.println(100 / value); success = true; catch (InputMismatchException ex) { System.out.println("Erro ao ler valor"); in.nextline(); // Discards line catch (ArithmeticException ex) { System.out.println("Erro de cálculo: " + ex.getmessage()); while(!success); in.close(); System.out.println("OK"); Valor? abc Erro ao ler valor Valor? 0 Erro de cálculo: / by zero Valor? 20 5 OK 4
Lançar e capturar exceções Instrução throw exp Em que exp refere um objeto de uma classe derivada de Throwable A execução termina abruptamente não executando o restante código do(s) método(s) É procurado o catch adequado à exceção pela ordem inversa dos métodos chamados A execução continua a partir desse catch setradius(-10) m1(c) call call call m2(c,-10) main( ) Procura catch adequado main() { Circle c=new Circle(); m1(c); public class Circle { private int radius; m1(circle c) { try { m2(c,-10); catch(exception e){ m2(circle c, int r) { c.setradius(r); public void setradius(int r) { if (r<0) throw new IllegalArgumentException("r < 0"); radius = r; invalidate(); 5
Lançar e capturar a exceção 1. Quando ocorre a condição excecional é criado um objeto que descreve essa condição new Exception() 2. O objeto da exceção é lançado terminando abruptamente o bloco de código em execução throw 3. O mecanismo de exceções determina qual é o ponto de captura (try/catch) mais próximo para a exceção no contexto da execução, andando para trás na ordem de invocação dos métodos. 4. É executado o código de captura adequado à exceção try { catch( Exception ex) { 5. É executado o código do bloco finally, caso exista catch(exception ex) { finally { 6. A execução continua normalmente após o ponto de captura 6
Hierarquia de exceções Error Lançadas pela JVM em situações graves Não verificadas pelo compilador (unchecked) Não devem ser definidas classes derivadas de Error Ex: StackOverflow Exception checked Verificadas pelo compilador Têm que ser capturadas e tratadas no programa Origem em fatores externos ao programa Ex: FileNotFound RunTimeException unchecked Não verificadas pelo compilador Originadas por erros de programação Não deve ocorrer na versão final Ex: divisão por zero em inteiros 7
Características das exceções A classe Throwable implementa as características herdadas pelas exceções Mensagem Descrição detalhada da exceção Causa Quando a exceção é provocada por outra Pode ser null Stack de chamadas Os métodos chamados desde main() até ao método que lançou a exceção, por ordem inversa java.lang.nullpointerexception at MyClass.mash(MyClass.java:9) at MyClass.crunch(MyClass.java:6) at MyClass.main(MyClass.java:3) 8
Exceções checked Código que pode lançar determinada exceção E checked, deve: Estar envolvido num bloco try com catch que capture essa exceção ou então Pertencer a um método que indique que pode lançar essa exceção para quem o chamar void m() { try { throw new E(); catch(e ex){ ou então void m() throws E { throw new E(); 9
Definição de novas exceções Novas exceções devem derivar de Exception ou RuntimeException conforme se pretenda que sejam checked ou unchecked. public class StackException extends RuntimeException { protected StackException(String msg) {super(msg); protected StackException() {super(); public class StackFull extends StackException { private int capacity; public StackFull(int cap) { super(" capacity="+cap); capacity = cap; public int getcapacity() { return capacity; public class StackEmpty extends StackException { 10
Relançar exceções public class Stack<T> { private T[] array; private int length = 0; Conversão para T[] não pode ser verificada pelo compilador @SuppressWarnings("unchecked") public Stack(int cap) { array = (T[]) new Object[cap]; public boolean isfull() { return length==array.length public void push(t elem) { try { array[length] = elem; ++length; catch (ArrayIndexOutOfBoundsException e) { throw new StackFull(array.length); Lança StackFull em vez de ArrayIndexOutOfBoundsException 11
Alterações no Java 7 Cláusulas cacth com várias exceções Reduz a duplicação de código na captura de exceções diferentes Scanner in; try { in = new Scanner(System.in); int value = in.nextint(); System.out.println(100/value); catch(inputmismatchexception ArithmeticException ex) { System.out.println("Erro: " + ex.getmessage()); finally { in.close(); Blocos try com recursos No finally faz close() dos recursos indicados no try Os recursos têm que implementar a interface AutoCloseable try (Scanner in = new Scanner(System.in)) { int value = in.nextint(); System.out.println(100/value); catch(inputmismatchexception ArithmeticException ex) { System.out.println("Erro: " + ex.getmessage()); 12