Programação Orientada por Objectos - Aula 5

34
Aula 5 Erros e casos excepcionais: conceitos; representação, criação, detecção e tratamento; boas práticas (e segurança)

description

Aula teórica 5 da unidade (disciplina) de Programação Orientada por Objectivos para os cursos de LIGE, LEI e LETI no ISCTE-IUL no 2.º semestre do ano lectivo de 2009/2010.

Transcript of Programação Orientada por Objectos - Aula 5

Page 1: Programação Orientada por Objectos - Aula 5

Aula 5

Erros e casos excepcionais: conceitos; representação, criação, detecção e tratamento; boas práticas (e segurança)

Page 2: Programação Orientada por Objectos - Aula 5

Na aula anterior…

A infra-estrutura aplicacional de colecções do Java (Java Collections Framework)

2009/2010 Programação Orientada por Objectos 2

Page 3: Programação Orientada por Objectos - Aula 5

Conceitos

Erro do utilizador humano

Não é um erro! É uma situação normal e expectável. Deve lidar-se com situações deste tipo usando as ferramentas usuais de controlo de fluxo do Java.

Caso excepcional

Os casos excepcionais fazem parte da lógica do programa, embora não possam ser considerados parte da seu fluxo de operação normal. Muitas vezes estão associados a problemas em recursos externos a que o programa precisa de recorrer.

Erro de programação

Os erros de programação são erros cometido pelos programadores e por isso não podem ser considerados parte da lógica do programa.

Erros no ambiente de execução

São erros que ocorrem no ambiente de execução do programa, não correspondendo nem a casos excepcionais, nem a erros de programação; não são parte da lógica do programa.

2009/2010 Programação Orientada por Objectos 3

Page 4: Programação Orientada por Objectos - Aula 5

Representação e criação

Em Java, casos excepcionais, erros de programação e erros no ambiente de execução representam-se através de lançáveis

Os lançáveis são criados e lançados Explicitamente: throw Implicitamente: assert Automaticamente: JVM, por exemplo Por métodos sobre os quais não temos controlo

2009/2010 Programação Orientada por Objectos 4

Page 5: Programação Orientada por Objectos - Aula 5

Detecção e tratamento

Lançáveis em Java podem ser capturados Para lidar integralmente com um caso

excepcional Para lidar parcialmente com um caso

excepcional Apenas para “arrumar a casa” , quando

não se sabe lidar com um caso excepcional

Para terminar o programa de forma adequada em caso de erro de programação ou de erro no ambiente de execução

2009/2010 Programação Orientada por Objectos 5

Isto não é uma recuperação, mas sim um elegante harakiri.

Page 6: Programação Orientada por Objectos - Aula 5

Programação Orientada por Objectos

Lançáveis Java

Usados para representar Casos excepcionais Erros de programação Erros no contexto de execução de um programa

São objectos de classes pertencentes à hierarquia com base na classe Throwable

São lançáveis através da instrução throw

Lançamento interrompe o fluxo normal de um programa

2009/2010 6

Page 7: Programação Orientada por Objectos - Aula 5

Hierarquia de lançáveis em Java

2009/2010 Programação Orientada por Objectos 7

Throwable

Error

VirtualMachineError

AssertionError

Exception

IOException

RuntimeException

ArithmeticException

NullPointerException

Erros de programação (excepto violação de pré-condições em contratos não privados).

Erros no ambiente de execução.

Erros de programação correspondentes a violação de pré-condições em contratos não privados.

Casos excepcionais.

Page 8: Programação Orientada por Objectos - Aula 5

Hierarquia de lançáveis em Java Throwable

Error▪ VirtualMachineError▪ …▪ AssertionError

Exception ▪ IOException▪ …▪ RuntimeException▪ ArithmeticException▪ NullPointerException▪ IndexOutOfBoundsException▪ …

Erros de programação (excepto violação de pré-condições em contratos não privados). Criação implícita quando asserção falha. Normalmente irrecuperáveis.

Erros de programação correspondentes a violações pré-condições de contratos não privados. Criação explícita. Lançamento com throw. Normalmente irrecuperáveis.

2009/2010 8Programação Orientada por Objectos

Erros no ambiente de execução. Criação automática. Normalmente irrecuperáveis.

Casos excepcionais. Criação explícita. Lançamento com throw. Normalmente recuperáveis.

Page 9: Programação Orientada por Objectos - Aula 5

Características

Ocorrência Classe Criação Instrução

Recuperação1

Caso excepcional Exception2 Explícita throw Sim

Erro de programação3

RuntimeException Explícita throw Não

Erro de programação4

AssertionError Implícita assert Não

Erros no ambiente de execução

Error5 Automática

- Não

2009/2010 Programação Orientada por Objectos 9

1 Para aplicações não críticas.2 Excepto RuntimeException e derivadas.3 Para violações de pré-condições em contratos não privados.4 Para todos os restantes casos.5 Excepto AssertionError.

Possibilidade de lançamento tem de ser declarada!

Page 10: Programação Orientada por Objectos - Aula 5

Algumas RuntimeException

2009/2010 Programação Orientada por Objectos 10

Excepção UtilizaçãoIllegalArgumentException Argumento de método não é válido.IllegalStateException Estado de objecto é inválido ou não

permite a operação.NullPointerException Tentativa de acesso a instância

através de referência nula.IndexOutOfBoundsException Índice de matriz ou colecção fora dos

limites válidos.ConcurrentModificationException Tentativa de alteração de objecto em

momento em que tal não é permitido (e.g., alteração de lista concorrente com iteração dessa lista).

UnsuportedOperationException Classe do objecto não suporta a operação em questão.

Page 11: Programação Orientada por Objectos - Aula 5

Lançamento explícito para caso excepcional

public void someMethod(…) throws SomeException { …

if (…) throw new SomeException("Informative message");

…}

Declaração de possibilidade de lançamento:• Obrigatória para Exception (excepto RuntimeException).• Não recomendada para restantes casos (Error e RuntimeException).

2009/2010 11Programação Orientada por Objectos

Page 12: Programação Orientada por Objectos - Aula 5

Lançamento explícito para erro de programação

static public double squareRoot(final double value) { if (value < 0.0) throw new IllegalArgumentException( "Illegal value " + value + ", should be 0 ≤ value"); …}

2009/2010 12Programação Orientada por Objectos

Violação de pré-condição em contrato não privado.

Page 13: Programação Orientada por Objectos - Aula 5

Delegação ou declaração de passagem (throws)

public void someMethod(…) throws SomeException { …

anObject.someOtherMethod(…);

… // only if no exception is thrown.}

2009/2010 Programação Orientada por Objectos 13

Page 14: Programação Orientada por Objectos - Aula 5

Lidando com caso excepcionalpublic void someMethod(…) { try { … anObject.someOtherMethod(…);

… // only if no exception is thrown. } catch (final SomeException exception) { … // fix the problem using information available. }

… // continue execution.}

2009/2010 14Programação Orientada por Objectos

Page 15: Programação Orientada por Objectos - Aula 5

Arrumando a casa com finally

public void someMethod(…) { try { … anObject.someOtherMethod(…); … } catch (final SomeException exception) { … } finally { … // clean house in any case. }

…}

2009/2010 15Programação Orientada por Objectos

Bloco finally executado mesmo no caso de excepções não capturadas, retornos, novos lançamentos, asserções falhadas, etc.

Page 16: Programação Orientada por Objectos - Aula 5

Lidando parcialmente com caso excepcional

public void someMethod(…) throws SomeException { try { … anObject.someOtherMethod(…);

… } catch (final SomeException exception) { … // fix part of the problem using information

available. throw exception; }

…}

2009/2010 16Programação Orientada por Objectos

Relançamento da excepção capturada.

Page 17: Programação Orientada por Objectos - Aula 5

Informação adicional sobre a ocorrência

public void someMethod(…) throws SomeOtherException { try { … anObject.someOtherMethod(…);

… } catch (final SomeException exception) { … // clean house if necessary. throw new SomeOtherException( "Informative message", exception); }

…}

2009/2010 17Programação Orientada por Objectos

Lançável capturado é a causa do novo lançável.

Apenas se se tratar de um caso excepcional.

Page 18: Programação Orientada por Objectos - Aula 5

Captura múltipla

public void someMethod(…) { try { … } catch (final SomeException exception) { … } catch (final RuntimeException exception) { … } catch (final IOException exception) { … } catch (final Exception exception) { … }

…}

Excepções mais específicas têm de estar primeiro.

2009/2010 18Programação Orientada por Objectos

Page 19: Programação Orientada por Objectos - Aula 5

Operação printStackTrace

public void someMethod(…) { …

try { … } catch (final SomeException exception) { exception.printStackTrace(); … }

…}

Imprime uma representação da pilha de invocações no momento em que a excepção foi lançada.

pt.iscte.dcti.poo.exceptions.SomeExceptionat pt.iscte.dcti.poo.SomeClass.someMethod(SomeClass.java:16)at pt.iscte.dcti.poo.SomeOtherClass.someOtherMethod(SomeOtherClass.java:9)at pt.iscte.dcti.poo.MainClass.main(MainClass.java:36)

2009/2010 19Programação Orientada por Objectos

Page 20: Programação Orientada por Objectos - Aula 5

Contratos: documentação e verificação

/** * Returns the double closest to the square root of its argument * value. * * @pre 0 ≤ value * @post … * @param value the value whose square root will be

approximated * @throws IllegalArgumentException If value < 0 */static public double squareRoot(final double value) { if(value < 0) throw new IllegalArgumentException(“Message"); … assert … : "Informative message"; return result;}

2009/2010 20Programação Orientada por Objectos

As asserções, por omissão, estão desactivadas. Para que tenham algum efeito tem de se executar a JVM com a opção -ea.

Page 21: Programação Orientada por Objectos - Aula 5

Invariante de instância

public Rational(final int numerator, final int denominator) { if(denominator == 0) throw new IllegalArgumentException("Message");

this.numerator = numerator; this.denominator = denominator; normalize();

checkInvariant();}

private void checkInvariant() { assert 0 < denominator : "…"; assert gcd(numerator, denominator) == 1 : "…";}

O invariante de instância é a condição que todas as instâncias de uma classe têm de verificar para que estejam num estado correcto.

Onde? No final dos construtores, no início de métodos não modificadores e no início e no fim de métodos modificadores.

2009/2010 21Programação Orientada por Objectos

Page 22: Programação Orientada por Objectos - Aula 5

Métodos privados

private void reduce() { assert denominator != 0;

if (denominator < 0) { denominator = -denominator; numerator = -numerator; }

final int gcd = gcd(numerator, denominator); numerator /= gcd; denominator /= gcd;

assert mdc(numerator, denominator) == 1 : "…"; assert 0 < denominator : "…";}

2009/2010 Programação Orientada por Objectos 22

Pré-condição de método privado (parte da implementação da classe) verificada com asserção.

Nos métodos privados não se verifica o invariante de instância, pelo menos enquanto tal.

Page 23: Programação Orientada por Objectos - Aula 5

Lançáveis definidos pelo programador

public class SomeException extends Exception {

public Exception() { }

public Exception(final String message) { super(message); }

public Exception(final String message, final Throwable cause) { super(message, cause); }

public Exception(final Throwable cause) { super(cause); }

}2009/2010 23Programação Orientada por Objectos

Page 24: Programação Orientada por Objectos - Aula 5

Boas práticas

Distinga claramente a natureza dos erros e casos excepcionais

Lide com cada ocorrência usando os mecanismos adequados (e convencionais) à sua natureza

2009/2010 Programação Orientada por Objectos 24

Page 25: Programação Orientada por Objectos - Aula 5

Boas práticas

Use assert apenas para erros de programação▪ Pré-condições de métodos privados▪ Pós-condições▪ Invariantes de instância▪ Asserções propriamente ditas

Use throw▪ Para erros de programação▪ Pré-condições de métodos não privados

▪ Casos excepcionais2009/2010 25Programação Orientada por Objectos

Page 26: Programação Orientada por Objectos - Aula 5

Boas práticas

Não tente recuperar de uma ocorrência sem antes perceber a sua causa

Não desactive as asserções durante a operação normal do software senão quando tiverem um impacte negativo significativo sobre o seu desempenho

Tente recorrer a lançáveis já existentes na biblioteca padrão do Java

2009/2010 Programação Orientada por Objectos 26

Page 27: Programação Orientada por Objectos - Aula 5

Boas práticas

Documente possibilidade de lançamento de de RuntimeException (e classes derivadas) quando esse lançamento puder ocorrer devido erros na utilização da interface da operação

Lembre-se que pode capturar um lançável e lançar um outro que torne mais claro qual o problema (não deve abusar desta estratégia)

2009/2010 Programação Orientada por Objectos 27

Page 28: Programação Orientada por Objectos - Aula 5

Boas práticas: segurança Escreva o seu código de modo a que o

lançamento de um lançável num método deixe o programa no mesmo estado em que estava antes da operação correspondente ser invocada

Se isso não for possível, escreva o código de modo a, pelo menos, deixar todos os objectos num estado válido

2009/2010 Programação Orientada por Objectos 28

Page 29: Programação Orientada por Objectos - Aula 5

Boas práticas: testes

Para cada unidade (classe ou conjunto de classes intimamente ligadas) crie um caso de teste JUnit

Crie os testes antes mesmo de começar a desenhar a unidade: pensar nos testes ajuda a perceber melhor que interface deve ter a unidade

Teste sempre as situações limite e casos especiais (referências nulas, cadeias de caracteres vazias, valores numéricos no limite, etc.)

2009/2010 29Programação Orientada por Objectos

Page 30: Programação Orientada por Objectos - Aula 5

Boas práticas: testes

Lembre-se que os testes se devem basear apenas na interface não privada da unidade (testes de caixa preta)

Evite alterar a interface não privada quando fizer alterações a uma unidade

Se precisar de alterar a interface não privada de uma unidade, actualize todos testes e reveja todos os contratos e respectiva documentação

Quando alterar a implementação de uma unidade, reveja o seu invariante e execute todos os seus testes

2009/2010 30Programação Orientada por Objectos

Page 31: Programação Orientada por Objectos - Aula 5

A reter…

Detecção e tratamento de ocorrências fundamental para boa programação

Princípio subjacente à programação em linguagens como o Java é que quanto mais cedo se detectarem erros, mais fácil é corrigi-los e menor o seu impacte

Asserções usam-se para expressar condições que devem ser verdadeiras para que o programa esteja correcto

Asserções antecipam detecção de erros de programação e melhoram sua localização

2009/2010 31Programação Orientada por Objectos

Page 32: Programação Orientada por Objectos - Aula 5

A reter…

A relação das excepções declaradas com a operação em causa deve ser clara e deve ser documentada

Detecção de erro de programação ou de erro no ambiente de execução do programa deve levar sistema, se não crítico, a cometer um elegante harakiri, tão simpático para utilizadores quanto possível

Um programa honrado percebe quando falha e extingue-se voluntariamente, não deixando que erros se propaguem

2009/2010 Programação Orientada por Objectos 32

Page 33: Programação Orientada por Objectos - Aula 5

A ler para as próximas aulas ...

Capítulo 18 do livro:

Y. Daniel Liang, Introduction to Java Programming, 7.ª edição, Prentice-Hall, 2008.ISBN: 978-0-13-605966-0

2009/2010 Programação Orientada por Objectos 33

Page 34: Programação Orientada por Objectos - Aula 5

Sumário

Erros e casos excepcionais Conceitos▪ Excepções ▪ Erros de programação▪ Erros no ambiente de execução

Representação, criação, detecção e tratamento▪ Excepções Java▪ Asserções Java

Boas práticas (incluindo segurança)2009/2010 Programação Orientada por Objectos 34