exceções aula 13 - cin.ufpe.brif669/material/aulasnovas2016/13-excecoes.pdf · exceções...

34
Ricardo Massa F. Lima [email protected] Sérgio C. B. Soares [email protected] Exceções AULA 13 Introdução a Programação – IF669 http://www.cin.ufpe.br/~if669

Upload: vuthuan

Post on 09-Nov-2018

224 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Ricardo Massa F. Lima [email protected]

Sérgio C. B. Soares [email protected]

Exceções

AULA 13

Introdução a Programação – IF669 http://www.cin.ufpe.br/~if669

Page 2: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Exceções

Objetivo

Depois desta aula você será capaz de desenvolver sistemas robustos, notificando e tratando casos de erro na execução de métodos através do mecanismo de exceções de Java.

Page 3: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Classe de Contas: Definição

public class Conta { private String numero; private double saldo; ... public void debitar(double valor) { saldo = saldo - valor; } }

Como evitar débitos acima do limite permitido?

Page 4: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Desconsiderar Operação

public class Conta { private String numero; private double saldo; ... public void debitar(double valor) { if (valor <= saldo) saldo = saldo - valor; } }

Page 5: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Desconsiderar Operação

n  Problemas: –  quem solicita a operação não tem como saber se

ela foi realizada ou não

–  nenhuma informação é dada ao usuário do sistema

Page 6: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Mostrar Mensagem de Erro

public class Conta { private String numero; private double saldo; ... public void debitar(double valor) { if (valor <= saldo) saldo = saldo - valor; else System.out.print("Saldo Insuficiente"); } }

Page 7: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Mostrar Mensagem de Erro

n  Problemas: –  informação é dada ao usuário do sistema, mas

nenhuma sinalização de erro é fornecida para métodos que invocam debitar

–  supõe que a interface com o usuário é modo texto

–  entrelaçamento entre do código da camada de negócio com o código da camada de interface com o usuário: §  cria uma forte dependência entre a classe Conta

e sua interface com o usuário

Page 8: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Retornar Código de Erro

public class Conta { private String numero; private double saldo; ... public boolean debitar(double valor) { boolean r = false; if (valor <= saldo) { saldo = saldo - valor; r = true; } else r = false; return r; } }

Page 9: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Retornar Código de Erro

n  Problemas: –  dificulta a definição e o uso do método –  não torna a causa ou o tipo do erro explícito –  métodos que invocam debitar têm que testar o

resultado retornado para decidir o que deve ser feito

–  A dificuldade é maior para métodos que retornam valores: §  e se debitar já retornasse um outro valor

qualquer? O que teria que ser feito?

Page 10: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Código de Erro: Problemas public class Banco { private RepositorioContas contas; // ... public int debitar(String numero, double valor) { int erro = 0; Conta c = contas.procurar(numero); if (c != null) { boolean b = c.debitar(valor); if (b) erro = 0; else erro = 2; } else erro = 1; return erro; } }

Page 11: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Mecanismo de Exceções

n  Ao invés de códigos, teremos exceções...

n  Exceções são objetos de classes derivadas da superclasse Exception

n  Define-se subclasses de Exception para

–  oferecer informações extras sobre a falha, ou

–  distinguir os vários tipos de falhas

11

Page 12: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Tratamento de Exceções Exemplos de ocorrência de Exceções

•  Acesso a um local do array fora dos limites •  Estouro aritmético •  Divisão por zero •  Esgotamento de memória •  Cast inválido •  Conta não encontrada no repositório •  Saldo insuficiente

12

As duas últimas são exceções específicas de aplicações e precisam

ser definidas explicitamente

Page 13: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Definindo Exceções (1)

public class SIException extends Exception { private double saldo; private String numero; public SIException(double saldo, String numero) { super ("Saldo Insuficiente!"); this.saldo = saldo; this.numero = numero; } public double getSaldo() { return saldo; } // ... }

Page 14: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Definindo Exceções (2)

public class CNEException extends Exception { public CNEException() { super (”Conta não encontrada"); } }

Page 15: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Definindo Métodos com Exceções (1)

public class Conta { // ... public void debitar(double valor) throws SIException { if (valor <= saldo) saldo = saldo - valor; else { SIException e; e = new SIException(saldo,numero); throw e; } } }

Page 16: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Definindo Métodos com Exceções (2)

public class RepositorioContasArray implements RepositorioContas { private Conta[] contas; // ... public Conta procurar(String numero) throws CNEException { Conta c = null; for (int i=0; i<indice && !achou ; i++) { //... } if (!achou) throw new CNEException(); return c; } }

Page 17: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Definindo Métodos com Exceções (3)

public class Banco { private RepositorioContas contas; // ... public void debitar(String n, double v) throws SIException, CNEException { Conta c = contas.procurar(n); c.debitar(v); } }

Page 18: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Definindo e Levantando Exceções

n  Res metodo(Pars) throws E1,...,EN

n  Todos os tipos de exceções levantadas no corpo de um método devem ser declaradas na sua assinatura

n  Levantando exceções: throw obj-exceção

n  Fluxo de controle e exceção são passados para o ponto onde ocorreu a chamada para o método que gerou a exceção (executou o comando throw)

Page 19: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Fluxo de controle

public class Banco { private RepositorioContas contas; // ... public int debitar(String n, double v) throws SIException, CNEException { Conta c = contas.procurar(n); c.debitar(v); } } Se contas.procurar(n) gerar uma exceção, o

controle de fluxo volta para quem chamou

Page 20: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Já sabemos gerar exceções

n Mas onde e como tratar as mesmas?

– O que fazer quando um erro acontece?

Page 21: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Tratando Exceções

Antes... try { ... banco.debitar(“123-4”,90.00); ... } catch (SIException e) { System.out.print(e.getMessage()); System.out.print(“ Conta/saldo: ”); System.out.print(e.getNumero()+ “ / ” + e.getSaldo()); } catch (CNEException e) {...} Depois...

Page 22: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Tratando Exceções

n  A execução do try termina assim que uma exceção é levantada

n  O primeiro catch de um supertipo da exceção é executado e o fluxo de controle passa para o código seguinte ao último catch

n  Se não houver nenhum catch compatível, a exceção e o fluxo de controle são passados para quem chamou o código (método) que contém o try/catch

Page 23: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Tratando Exceções: Forma Geral

try { ... } catch (E1 e1) { ... } ... } catch (En en) { ... } finally { ... }

O bloco finally é opcional desde que exista pelo menos um bloco catch

Page 24: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Tratando Exceções

n  O bloco finally é sempre executado mesmo

–  após a terminação normal do try

–  após a execução de um catch

–  quando não existe nenhum catch compatível

n  Quando o try termina normalmente ou um catch é executado, o fluxo de controle é passado para o código após o bloco finally (depois deste ser executado)

Page 25: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Tratamento de Exceções

n  Verificação de Exceções

–  Não verificadas

§  RuntimeException

§  NullPointerException

§  NumberFormatException

–  Verificadas

§ O compilador emite uma mensagem de erro indicando que a exceção deve ser capturada

25

Page 26: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Interfaces e exceções

n  Uma interface deve declarar na assinatura dos seus métodos quais exceções (erros) os métodos (serviços) podem levantar (gerar)

n  Implementações da interface (classes) podem ser mais eficientes e gerar menos erros do que os esperados

–  devem ser sempre um subconjunto das exceções definidas na interface

O MESMO VALE PARA MÉTODOS DE CLASSES ABSTRATAS

Page 27: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Exemplo

public interface RepositorioContas { void inserir(ContaAbstrata conta) throws RepositorioException; // ... }

public class RepositorioContasArray implements RepositorioContas { public void inserir(ContaAbstrata conta){ // nunca dará erro se o array encher } // ... }

Page 28: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Repoisitório com array (1/5)

public class RepositorioContasArray implements RepositorioContas { private ContaAbstrata[] contas; private int indice; public RepositorioContasArray(int tamanho) { contas = new ContaAbstrata[tamanho]; indice = 0; } public void inserir(ContaAbstrata conta) { contas[indice] = conta; indice = indice + 1; }

Page 29: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Repoisitório com array (2/5)

public ContaAbstrata procurar(String numero) throws ContaNaoEncontradaException { ContaAbstrata resposta = null; int i = this.getIndice(numero); if (i == this.indice) { throw new ContaNaoEncontradaException(); } else { resposta = this.contas[i]; } return resposta; }

Page 30: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Repoisitório com array (3/5)

public void remover(String numero) throws ContaNaoEncontradaException { int i = this.getIndice(numero); if (i == this.indice) { throw new ContaNaoEncontradaException(); } else { this.indice = this.indice - 1; this.contas[i] = this.contas[this.indice]; this.contas[this.indice] = null; } }

Page 31: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Repoisitório com array (4/5)

public void atualizar(ContaAbstrata conta) throws ContaNaoEncontradaException { int i = this.getIndice(conta.getNumero()); if (i == this.indice) { throw new ContaNaoEncontradaException(); } else { this.contas[i] = conta; } } public boolean existe(String numero) { int i = this.getIndice(numero); return (i != this.indice); }

Page 32: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Repoisitório com array (5/5) private int getIndice(String numero) { String n; boolean achou = false; int i = 0; while ((!achou) && (i < this.indice)) { n = contas[i].getNumero(); if (n.equals(numero)) { achou = true; } else { i = i + 1; } } return i; } }

Page 33: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Exercício (1) n  Utilize a solução dos exercícios da última aula www.cin.ufpe.br/~if669/material/solucoes/aula14.zip

n  Defina a exceção ContaNaoEncontradaException no pacote aula15.br.ufpe.cin.dados

n  Modifique a classe RepositorioContasArray para lançar esta exceção ao invés de RuntimeException quando a conta não for encontrada –  Faça os ajustes necessários nas demais classes e

interface da aplicação n  Mova a classe Programa para o pacote aula15.br.ufpe.cin.ui. Ela deve tratar a exceção dando uma mensagem de erro para o usuário

n  Teste o programa

Page 34: Exceções AULA 13 - cin.ufpe.brif669/material/aulasNovas2016/13-Excecoes.pdf · Exceções Objetivo Depois desta aula você será capaz de desenvolver sistemas robustos, notificando

Exercício (2) n  Defina a classe SaldoInsuficienteException

no pacote aula15.br.ufpe.cin.banco –  Modifique a classe ContaAbstrata para lançar esta

exceção e ajuste as demais classes –  Teste o programa

n  Defina a classe ContaJaCadastrarException no pacote aula15.br.ufpe.cin.banco –  O método cadastrar da classe Banco deve lançar

esta exceção quando já existir uma conta com o mesmo número da conta a ser cadastrada

–  Ajuste das demais classes e teste o programa n  Crie e utilize exceções específicas em outros casos

onde está sendo utilizada RuntimeException