A exceção - WordPress.com

Propaganda
3 – Exceções
“Nature provides exceptions to every rule.“
- Margaret Fuller
“Nosso software não tem bugs.”
“Nós não encontramos bugs em nosso
software.”
• Entradas (as vezes maliciosa), falhas na Rede,
falhas no Banco de Dados...
Tratamento de erros e exceções
Contextualização
• Implementação do programa que executa nos
caixas de auto-atendimento dos bancos.
3
Motivação
• O que acontece com o método saca(1000)?
4
• Algum problema nisso?
Como saber se o usuário passou um valor <0?
Magic numbers: mudar o retorno de boolean para int, e tratar cada número como código
de um erro que ocorreu.
• Nós perdemos o retorno do método e o valor devolvido é "mágico" e só legível
perante extensa documentação;
• Continuamos não obrigando o programador a tratar esse retorno (ele pode
esquecer...) e, caso ele esqueça, seu programa rodará em um estado inconsistente.
5
Exceção
• Por esses e outros motivos, utilizamos um código
diferente em Java para tratar aquilo que chamamos
de exceções: os casos onde acontece algo que,
normalmente, não iria acontecer.
– Exemplo: o argumento do saque inválido, além do limite
disponível ou um valor negativo
•
Uma exceção representa uma situação que
normalmente não ocorre e representa algo de estranho
ou inesperado no sistema.
6
Estrutura: blocos try-catch
try {
// Insira algum código aqui que possa causar algum
// tipo de exceção.
// Podemos ter muitas linhas de código aqui
// ou apenas uma.
}
catch (MinhaExcecao ex) {
// Insira um código aqui que manipule essa exceção.
}
finally{
// libere os recursos alocados no “try”
}
Execício I
• Antes de resolvermos o nosso
problema, vamos ver como a
Java Virtual Machine age ao se
deparar
com
situações
inesperadas, como divisão por
zero ou acesso a um índice da
array que não existe.
– Para aprendermos os conceitos
básicos das exceptions do Java, teste
o seguinte código você mesmo (5
minutos)
– O que é impresso e qual a ordem de
execução dos métodos
8
Execício I
• Main  Metodo1  metodo2
– cada método tem suas variáveis
locais (só o método em questão
enxerga)
– Toda invocação de método é
empilhada na pilha de execução
(stack)
9
Resultado
Exceção: índice fora dos limites do array
stack trace, ou
rastro da pilha
10
Sistema de exceções do Java
• Quando uma exceção é lançada (throw), a JVM entra em estado de alerta
e vai ver se o método atual toma alguma precaução ao tentar (try)
executar esse trecho de código;
• Exceção é lançada no metodo2, mas
ele não toma nenhuma precaução (try);
•
•
JVM, pára a execução dele e desce um
stackFrame;
A exceção (batata quente) continua viva, pois
ninguém tratou ela. Logo, ela é passada
adiante.
• JVM volta pra o metodo1, mas ele
também não toma nenhuma precaução
com a exceção
ArrayIndexOutOfBoundsException;
• De modo similar, a exceção vai pro main,
que também não a trata, e assim o
programa explode e pára de funcionar!
ArrayIndexOutOfBounds
11
•
•
Obviamente, aqui estamos forçando esse caso e não faria sentido tomarmos cuidado com
ele. É fácil arrumar um problema desses: basta percorrermos a array no máximo até o
seu length.
Porém, apenas para entender o controle de fluxo de uma Exception, vamos colocar o
código que vai tentar (try) executar o bloco perigoso e, caso o problema seja do
tipo ArrayIndexOutOfBoundsException, ele será pego (caught). Repare que é interessante
que cada exceção no Java tenha um tipo... ela pode ter atributos e métodos.
12
?
13
• Retire o try/catch e coloque ele em volta da
chamada do metodo2.
?
14
• Faça
o
mesmo,
retirando
o
try
catch novamente e colocando em volta da
chamada do metodo1. Rode os códigos, o que
acontece?
?
•
A partir do momento que uma exception foi catched
(pega, tratada, handled), a execução volta ao normal a
partir daquele ponto.
15
Errors
Unchecked exceptions
Checked exceptions
Situações incomuns que
não são causados por erro
de implementação
Hierarquia
Geralmente são causadas
por indisponibilidades ou
inexistência do recurso
Geralmente são causadas
por erro de implementação
16
NullPointerException e
ClassCastException, são
checked
(obrigatoriamente
precisam ser tratadas) ou
unchecked / runtime?
17
Unchecked/RuntimeExceptions
• número/0  ArithmeticException
• acessar elemento fora dos limites de um array 
ArrayIndexOutOfBoundsException
• acessar atributos ou chamar métodos de referência
nula  NullPointerException
• Tentar converter uma variável de referência em um
tipo que não passa no teste É-UM (instanceof) 
ClassCastException
• Também são chamadas de Unchecked Exceptions
– Podem ser consertadas programaticamente
Unchecked/RuntimeExceptions
19
Checked Exceptions
• obriga a quem chama o método ou construtor (que
lança a exceção) a tratar essa exceção
– checked: o compilador checará se ela está sendo
devidamente tratada, diferente das anteriores, conhecidas
como unchecked
– caso não esteja sendo tratada, o código não compilará
Compila?
20
Como resolver?
1
2
21
Múltiplas exceções
1
2
3
22
Lançando exceções
throw está no imperativo,
ou seja, significa lance
algo foi usado como
argumento e o método
saca não gostou
RuntimeException é muito
genérica
23
Lançando exceções
É boa prática adicionar msg
explicando a exceção
E se o valor passado fosse negativo,
como resolveríamos esse problema?
24
1
O que colocar dentro do try?
Mas há ainda uma outra opção: imagine que, para o nosso sistema,
uma falha ao sacar da conta poupança deve parar o processo de
saques e nem tentar sacar da conta corrente.
2
25
Criando nossa própria Exceção
26
Discussão final
• Existe uma péssima prática de programação em java que é a de
escrever o catch e o throws com Exception.
– Existem códigos que sempre usam Exception pois isso cuida de todos
os possíveis erros. O maior problema disso é generalizar o erro. Se
alguém joga algo do tipo Exception para quem o chamou, quem
recebe não sabe qual o tipo específico de erro ocorreu e não vai
saber como tratar o mesmo.
• Sim, há casos onde o tratamento de mais de uma exception pode
ser feito de uma mesma maneira. Por exemplo, se queremos
terminar a aplicação tanto no caso de IOException quanto
em SQLException. Se fizermos catch(Exception e)para pegar esses
dois casos, teremos um problema: a aplicação vai parar mesmo que
outra exceção seja lançada. A solução correta seria ter dois catches,
mas aí teríamos código repetido. Para evitar o código repetido,
podemos usar o multi-catch do Java 7, que permite um mesmo
catch cuidar de mais de 1 exceção, através da sintaxe:
catch(IOException | SQLException e) { ... } .
27
Referências
• Essa aula utilizou os exemplos das apostilas
caelum e do livro de certificação Java (SCJP
por Kathy Sierra).
• Leitura adicional:
http://blog.caelum.com.br/lidando-comexceptions/
28
Download