Orientação a Objetos e a Linguagem Java

Propaganda
Orientação a Objetos e a Linguagem
Java
Afrânio Assis
[email protected]
Novembro/2006
1
Exceções e Tratamento de Erros
Novembro/2006
2
Introdução
• Nem todos os erros podem ser detectados
em tempo de compilação (Ex: Divisão por
zero).
• Algumas linguagens, como C, tratam esses
erros através do retorno de valores
especiais (-1, 0, 1) e da modificação de
flags globais.
• Nesses casos, quem recebe o erro deve
verificar o valor retornado ou a flag global
para descobri-lo.
Novembro/2006
3
Introdução
• Em Java, os erros que não podem ser
detectados em tempo de compilação são
chamados Exceções.
• Algumas situações indesejáveis também
podem ser definidas como exceções.
• Java oferece um mecanismo para o
tratamento de exceções, que torna o código
mais legível.
Novembro/2006
4
Lançamento de Exceções
• No ponto da ocorrência de uma exceção:
– geralmente, não sabemos o que fazer
– sabemos que não podemos continuar,
devemos parar
– alguém, em algum lugar, deve saber o que
fazer, ou seja, deve saber tratar a exceção.
• Quando uma exceção ocorre, o fluxo
normal de execução é interrompido e um
objeto que representa a exceção é criado e
lançado.
y = 0;
x = x / y;
Novembro/2006
// Divisão por zero! Exceção lançada
5
Lançamento de Exceções
• Em um local apropriado a exceção será
capturada e tratada.
• No tratamento deve ser feito o que for
necessário para que o programa continue
funcionando normalmente e para que os
interessados saibam o que ocorreu.
• Uma exceção também pode ser lançada
pelo próprio programador.
if (y == 0)
throw new ArithmeticException();
x = x / y;
Novembro/2006
6
Lançamento de Exceções
if (y == 0)
throw new ArithmeticException(“divisão por zero!”);
x = x / y;
throw <objeto_exceção>;
• A palavra reservada throw
– O fluxo de execução normal é interrompido
– A execução continua no local de tratamento da
exceção
– Podemos lançar qualquer objeto do tipo Throwable
(que possui as subclasses Erro e Exception)
Novembro/2006
7
Capturando uma Exceção
• Vantagem do tratamento de exceções em Java
– O programador se preocupa apenas com a essência
do problema, casos excepcionais são tratados em
outro lugar
• Conceito de região protegida
– Trecho de código que pode produzir exceções, seguido
do código que pode tratar tais exceções
• O bloco try
– Bloco que delimita o trecho de código protegido com
relação ao surgimento de exceções
try
{
// região protegida
}
Novembro/2006
8
Capturando uma Exceção
• Manipuladores de exceção
–
–
–
–
–
a exceção lançada deve ser tratada em algum lugar
este lugar é o manipulador de exceção
existe um para cada tipo de exceção
seguem imediatamente o bloco try
denotados pela palavra reservada catch
try
{
// região protegida
}
catch (Tipo1 id1) {}
catch (Tipo2 id2) {}
Novembro/2006
9
Capturando uma Exceção
try {
if (y == 0)
throw new ArithmeticException("divisão por zero!");
x = x / y;
}
catch(ArithmeticException e){
//tratamento da exceção
}
• Cada cláusula catch (manipulador de exceção)
– É como se fosse um método com um único
parâmetro
– Identificador pode ser utilizado normalmente
dentro do escopo
Novembro/2006
10
Capturando uma Exceção
• Mecanismo de tratamento de exceções
– procura a primeira cláusula catch que case
com o tipo de exceção que foi lançada
– ao entrar no manipulador de exceção, a
exceção é considerada tratada
– busca por novos manipuladores termina
• busca apenas um manipulador
Novembro/2006
11
Criando Classes de Exceções
• Podemos criar nossas próprias classes de
exceções
– Útil se forem gerados erros não previstos na
hierarquia de classes de exceções de Java
– Temos que herdar de alguma classe de
exceção da hierarquia de exceções de Java
• Devemos procurar uma exceção que possua
sentido próximo (coerente) da exceção que
estamos criando
Novembro/2006
12
// Inheriting your own exceptions.
class SimpleException extends Exception {}
public class SimpleExceptionDemo {
public void m() throws SimpleException {
System.out.println("Throwing SimpleException from m()");
throw new SimpleException ();
}
public static void main(String[] args) {
SimpleExceptionDemo sed = new SimpleExceptionDemo();
try {
sed.m();
}
catch(SimpleException e) {
System.err.println("Caught it!");
}
}
}
Throwing SimpleException from m()
Caught it!
Novembro/2006
13
Criando Classes de Exceções
• Comentários
– O nome da classe deve fazer sentido! Ex:
IOException, PrintException,
CloneNotSupportedException, ...
– Temos que informar quando um método
levanta uma exceção não tratada internamente
(throws)
– Saída de erro padrão (System.err)
Novembro/2006
14
// Inheriting your own exceptions.
class MyException extends Exception {
public MyException() {}
// constructor with parameter
// call to the superclass constructor
public MyException(String msg){ super(msg); }
}
public class FullConstructors {
public static void f() throws MyException
{
System.out.println("Throwing MyException from f()");
throw new MyException();
}
public static void g() throws MyException
{
System.out.println("Throwing MyException from g()");
throw new MyException("Originated in g()");
}
Novembro/2006
15
public static void main(String[] args) {
try {
FullConstructors.f();
}
catch(MyException e) {
e.printStackTrace(System.err);
}
try {
FullConstructors.g();
}
catch(MyException e) {
e.printStackTrace(System.err);
}
}
}
Novembro/2006
16
Pilha de execução impressa na saída padrão de erro
Throwing MyException from f()
MyException
at FullConstructors.f(FullConstructors.java:16)
at FullConstructors.main(FullConstructors.java:28)
Throwing MyException from g()
MyException: Originated in g()
at FullConstructors.g(FullConstructors.java:22)
at FullConstructors.main(FullConstructors.java:37)
Mensagem passada no momento que a exceção foi criada
Novembro/2006
17
Palavra reservada throws
• Informa ao programador cliente que um
método pode lançar uma exceção
• Compõe a assinatura do método
• Não confundir com a palavra reserveda
throw
void f() throws TooBigException, TooSmallException
{
//...
}
Novembro/2006
18
Palavra reservada throws
• O uso de throws é obrigatório quando um
método lança uma exceção.
• O throws também pode ser usado sem que
a exceção declarada seja realmente
lançada pelo método.
– útil na criação de superclasses e interfaces
Novembro/2006
19
A classe Exception
• A classe mãe de todas as exceções em
Java
• O trecho abaixo trata qualquer exceção
catch (Exception e)
{
// Tratamento de qualquer exceção filha da
// classe “Exception”
}
Novembro/2006
20
A classe Exception
• Métodos
– String getMessage() - retorna a mensagem
informada na criação da exceção
– String getLocalizedMessage() - se não for
sobrescrito na subclasse, retorna a mesma mensagem
do método anterior. A idéia é que ele seja sobrescrito e
explique melhor a exceção.
– String toString() – informa o nome da classe e a
mensagem passada na criação da exceção.
– void printStackTrace() – imprime a pilha de
execução na saída padrão.
Novembro/2006
21
Relançado uma Exceção
• Relançando uma exceção
try {
//....
}
catch (Exception e) {
//Aqui a exceção é tratada. Em seguida, ela é
//relançada, conforme pode ser visto a seguir:
throw e;
}
• Um novo manipulador de exceção será procurado em
um contexto de mais alto nível
Novembro/2006
22
Relançado uma Exceção
try {
//....
}
catch (IOException e) {
throw e;
}
catch (Exception e) {
//....
}
• Quando existir mais de catch para um mesmo
try, a exceção relançada não será tratada nos
blocos catch seguintes
Novembro/2006
23
Relançado uma Exceção
• Quando relançado, o objeto exceção é
preservado, ou seja, ele mantém a
informação da pilha de execução original.
• Quando capturamos uma exceção
podemos lançar uma outra exceção,
diferente da capturada.
– útil quando queremos esconder algumas
exceções dos clientes de bibliotecas
Novembro/2006
24
Hierarquia de Exceções
Throwable
Exception
Error
RunTimeException
Novembro/2006
25
Hierarquia de Exceções
• Classe Throwable
– tudo que pode ser “lançado” como erro
– subclasses Error e Exception
– classe Error
• erros críticos
• geralmente não nos preocupamos com eles
• há pouco a ser feito quando ocorre, por exemplo,
um erro por falta de memória (OutOfMemoryError)
ou porque uma classe não foi encontrada
(NoClassDefFoundError)
– classe Exception
• tipo base de todas as exceções dos programas
Novembro/2006
26
Hierarquia de Exceções
• Caso especial: RunTimeException (herda
de Exception)
– classes de exceções levantadas
automaticamente pelo ambiente Java
– não precisamos incluí-las na cáusula throws de
um método
– ArithmeticException é um tipo de
RunTimeException
y = 0;
x = x / y;
Novembro/2006
// Divisão por zero!
27
Hierarquia de Exceções
• O que acontece quando não capturamos uma
RunTimeException?
– a exceção é repassada pelos métodos até o main()
– ao sair do programa, printStackTrace() é chamado para
a exceção
• RunTimeException representa erros que, geralmente,
são inconvenientes de verificar
– receber uma referência null como parâmetro de
método
– acesso fora dos limites de um array
Novembro/2006
28
A palavra reservada finally
• Usada para definir um bloco de comandos
que serão executados independentemente
de uma exceção ocorrer ou não
• Localizada após os manipuladores de
exceção (blocos catch)
try { /* região protegida */ }
catch (TipoExcecao1 e1) {}
catch (TipoExcecao2 e2) {}
finally
{
// comando finais sempre executados
}
Novembro/2006
29
// The finally clause is always executed.
class ThreeException extends Exception {}
public class FinallyWorks {
static int count = 0;
public static void main(String[] args) {
while(true) {
try {
if(count++ == 0) // Post-increment is zero first time
throw new ThreeException();
System.out.println("No exception");
} catch(ThreeException e) {
System.err.println("ThreeException");
} finally {
System.err.println("In finally clause");
if(count == 2) break; // out of "while"
}
}
ThreeException
}
In finally clause
}
No exception
In finally clause
Novembro/2006
30
A palavra reservada finally
• Útil para
– fechar de arquivos
– fechar de conexões de rede
– desfazer alguma transação feita pela metade
– ...
Novembro/2006
31
// Motivação para o uso do finally
class Switch {
boolean state = false;
boolean read() { return state; }
void on() { state = true; }
void off() { state = false; }
}
class OnOffException1 extends Exception {}
class OnOffException2 extends Exception {}
Novembro/2006
32
public class OnOffSwitch {
static Switch sw = new Switch();
static void f() throws OnOffException1, OnOffException2 {}
public static void main(String[] args) {
try {
sw.on();
f(); // Code that can throw exceptions...
sw.off(); // Poderia estar no finally
}
catch(OnOffException1 e) {
System.err.println("OnOffException1");
sw.off(); // Poderia estar no finally
}
catch(OnOffException2 e) {
System.err.println("OnOffException2");
sw.off(); // Poderia estar no finally
}
}
}
Novembro/2006
33
// Usando o finally teriamos:
public class OnOffSwitch {
static Switch sw = new Switch();
static void f() throws OnOffException1, OnOffException2 {}
public static void main(String[] args) {
try {
sw.on();
// Code that can throw exceptions...
f();
}
catch(OnOffException1 e)
{ System.err.println("OnOffException1"); }
catch(OnOffException2 e)
{ System.err.println("OnOffException2"); }
finally { sw.off(); }
}
}
Novembro/2006
34
Reagindo a exceções
• Quando ocorrer uma exceção podemos:
– chamar novamente o método que a provocou
passando novos parâmetros ou continuar sem
chamar tal método
– calcular um resultado alternativo
– fazer o que for possível no contexto corrente e
relançar a mesma exceção para um contexto
mais alto ou lançar outra exceção
– finalizar o programa
Novembro/2006
35
Considerações Finais
• A escrever o seguinte código:
• Ele captura até NullPointerException, mas
não faz nenhum tratamento.
• Ninguém saberá que um erro ocorreu.
Novembro/2006
36
Resumo do Funcionamento
1)Uma exceção é gerada;
2)A execução é interrompida;
3)Um objeto exceção é criado;
4)Uma referência a ele é direcionada para fora do
contexto atual;
5)O mecanismo de tratamento de exceções começa
a procurar pelo manipulador de exceção
apropriado para continuar a execução do
programa;
6)Nele o problema é tratado, com objetivo de que o
programa possa continuar executando.
Novembro/2006
37
Download