Baixe o app para aproveitar ainda mais
Prévia do material em texto
Prof. Leonardo Cruz. leonardocruz@id.uff.br Departamento de Computação, UFF Programação Orientada a Objetos com Java Manipulação de exceções Necessidade de mecanismos para tratamento de erros. Antes da POO: Variável global inteira com valores de 0 até n. Na ocorrência de uma exceção: Variável assumia um valor. Remetia uma mensagem de erro. Encerrava o programa. Introdução Depois da POO: Classes de erros. Possíveis tipos de erros e seus tratamentos são agrupados. Não há necessidade de interromper o programa. O mesmo erro é tratado quantas vezes for necessário. Introdução Ideia básica: “código ruim não será executado”. Nem todos os erros podem ser detalhados em tempo de compilação. Os que não podem devem ser lidados em tempo de execução. Estes últimos são o alvo da manipulação de exceções. Introdução Premissa básica: separar o processamento normal da manipulação de erros. Vantagens desse mecanismo: Permite concentrar em lugares diferentes o “código normal” do tratamento do erro. Simplifica a criação de programas grandes usando menos código. Torna o código mais robusto, ao garantir que não há erros sem tratamento. Introdução Exceção: problema que impede a continuação do método ou escopo em execução. Importante: exceção “problema normal”. Problema normal: há informação suficiente no contexto atual para lidar com ele. Exceção: não há informação suficiente. Disparar uma exceção: sair do contexto atual e relegar a solução a um contexto mais abrangente. Introdução Hierarquia de Exceção Leonardo Murta Tratamento de Exceções 8 Ver mais em: https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html Não podemos tratar Devemos tratar 9 Conceito Exceções representam situações de erro tratáveis, ocorridas durante a execução de um programa Divisão por zero Incapacidade de ler dados de um arquivo Geradores de exceções Interpretador Java: quando percebe uma situação de erro padrão (divisão por zero, falha de segurança, …) Métodos do programa: quando percebe uma situação de erro interna do programa (informação inválida, …) Leonardo Murta Tratamento de Exceções Exceções Ao disparar uma exceção, os seguintes eventos ocorrem: Um objeto exceção é criado. A execução é interrompida. O mecanismo de manipulação de exceções assume o controle o procura o manipulador de exceção adequado. O manipulador da exceção trata o problema. Exceções static void metodo2() { System.out.println("inicio do metodo2"); int[] array = new int[10]; for (int i = 0; i <= 15; i++) { array[i] = i; System.out.println(i); } System.out.println("fim do metodo2"); } }. Exemplo 1 Vamos tentar (try) executar o bloco perigoso e, caso o problema seja do tipo ArrayIndexOutOfBoundsException, ele será pego (caught). try/catch em volta do for, pegando ArrayIndexOutOfBoundsException. Exemplo 2 Exemplo 3 try/catch dentro do for, pegando ArrayIndexOutOfBoundsException Repare que, a partir do momento que uma exception foi catched (pega, tratada, handled), a execução volta ao normal a partir daquele ponto. Exemplo 4 try/catch ao redor do método, pegando ArrayIndexOutOfBoundsException public static void main(String[] args) { try { metodo2(); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("erro: " + e); } } static void metodo2() { System.out.println("inicio do metodo2"); int[] array = new int[10]; for (int i = 0; i <= 15; i++) { array[i] = i; System.out.println(i); } System.out.println("fim do metodo2"); } Exemplo 5 try/catch ao redor do método1 que chama o método2, pegando ArrayIndexOutOfBoundsException public static void main(String[] args) { System.out.println("inicio do main"); metodo1(); System.out.println("fim do main"); } static void metodo1() { System.out.println("inicio do metodo1"); metodo2(); System.out.println("fim do metodo1"); } static void metodo2() { System.out.println("inicio do metodo2"); int[] array = new int[10]; for (int i = 0; i <= 15; i++) { array[i] = i; System.out.println(i); } System.out.println("fim do metodo2"); } Exemplo 6 public static void metodo() { new java.io.FileInputStream("arquivo.txt"); } Exemplo 6 obriga a quem chama o método ou construtor a tratar essa exceção – delegando o tratamento public static void metodo() throws FileNotFoundException { new java.io.FileInputStream("arquivo.txt"); } public static void main(String[] args) { try { metodo(); } catch (FileNotFoundException e) { System.err.println("Erro de abertura de arquivo"); } } Observe que a IDE já avisa que é necessário tratar a exceção Porque? Mais de um erro ... Usando try catch try { objeto.metodoQuePodeLancarIOeSQLException(); } catch (IOException e) { // .. } catch (SQLException e) { // .. } Mais de um erro ... Usando throws public void metodo() throws IOException, SQLException { // .. objeto.metodoQuePodeLancarIOeSQLException(); } Mais de um erro ... Tratando e lançando public void metodo() throws IOException { try { objeto.metodoQuePodeLancarIOeSQLException(); } catch (SQLException e) { // .. } } Lançando exceções boolean saca(double valor) { if (this.saldo < valor) { return false; não possui crédito suficiente } else { this.saldo-=valor; return true; } } Lançando exceções void saca(double valor) { sem retorno if (this.saldo < valor) { throw new RuntimeException(); } throw (sem s) else { this.saldo-=valor; } } RuntimeException é a exception mãe de todas as exceptions throw vs throws A palavra chave throw, que está no imperativo, lança uma Exception. Isto é bem diferente de throws, que está no presente do indicativo, e que apenas avisa da possibilidade do método lançar uma exceção, obrigando o outro método que vá utilizar deste de se preocupar com essa exceção em questão Lançando exceções void saca(double valor) { sem retorno if (this.saldo < valor) { throw new IllegalArgumentException(); } throw (sem s) else { this.saldo-=valor; } } IllegalArgumentException é mais específica void saca(double valor) { if (this.saldo < valor) { throw new IllegalArgumentException(); } else { this.saldo-=valor; } } . . . try { cc.saca(100); } catch (IllegalArgumentExceptione) { System.out.println("Saldo Insuficiente"); } Lançando exceções void saca(double valor) { if (this.saldo < valor) { throw new IllegalArgumentException("Saldo insuficiente"); } else { this.saldo-=valor; } } . . . try { cc.saca(100); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); } Lançando exceções 1 ArithmeticException Arithmetic error, such as divide-by-zero. 2 ArrayIndexOutOfBoundsException Array index is out-of-bounds. 3 ArrayStoreException Assignment to an array element of an incompatible type. 4 ClassCastException Invalid cast. 5 IllegalArgumentException Illegal argument used to invoke a method. 6 IllegalMonitorStateException Illegal monitor operation, such as waiting on an unlocked thread. 7 IllegalStateException Environment or application is in incorrect state. 8 IllegalThreadStateException Requested operation not compatible with the current thread state. 9 IndexOutOfBoundsException Some type of index is out-of-bounds. 10 NegativeArraySizeException Array created with a negative size. 11 NullPointerException Invalid use of a null reference. 12 NumberFormatException Invalid conversion of a string to a numeric format. 13 SecurityException Attempt to violate security. Alguns tipos de exceções Lançando exceções - Exemplo 7 class Classe1{ static int quantidadeinstancias = 0; private int valor; public Classe1() throws UnsupportedOperationException{ if (quantidadeinstancias < 2){ this.valor = quantidadeinstancias; quantidadeinstancias++; } else { throw new UnsupportedOperationException("Não pode criar instância"); } } public int getValor(){ return this.valor; } } Lançando exceções - Exemplo 7 public static void main(String[] args) { try { Classe1 a = new Classe1(); System.out.println("Numero da Instância a = " + a.getValor()); Classe1 b = new Classe1(); System.out.println("Numero da Instância b = " + b.getValor()); Classe1 c = new Classe1(); System.out.println("Numero da Instância c = " + c.getValor()); } catch (UnsupportedOperationException e) { System.out.println(e.getMessage()); } } Numero da Instância a = 0 Numero da Instância b = 1 Não pode criar instancia finally finally que indica o que deve ser feito após o término do bloco try ou de um catch qualquer. finally finally que indica o que deve ser feito após o término do bloco try ou de um catch qualquer. try { // bloco try } catch (IOException ex) { // bloco catch 1 } catch (SQLException ex) { // bloco catch 2 } finally { // bloco que será sempre executado, independente // se houve ou não exception e se ela foi tratada ou não }
Compartilhar