Programação Orientada por Objectos - Aula 5
-
Upload
manuel-menezes-de-sequeira -
Category
Education
-
view
1.853 -
download
3
description
Transcript of 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)
Na aula anterior…
A infra-estrutura aplicacional de colecções do Java (Java Collections Framework)
2009/2010 Programação Orientada por Objectos 2
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
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
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.
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
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.
…
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.
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!
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.
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
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.
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
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
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.
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.
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.
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
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
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.
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
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.
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
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
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
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
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
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
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
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
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
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
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
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