Tratamento de Exceções Tratamento de Exceção Exemplos

Propaganda
DCC / ICEx / UFMG
Tratamento de Exceção
Uma exceção é uma indicação de
problema na execução do programa
Tratamento de Exceções
Exceção foge ao fluxo normal.
Ou seja, não ocorre com frequência
O objetivo do Tratamento de Exceção
(TE) é manter o programa funcionando
Eduardo Figueiredo
http://www.dcc.ufmg.br/~figueiredo
Ao invés de encerrar abruptamente
Aumenta a robustez
Exemplos de Exceções
Vantagens de TE
ArrayIndexOutOfBoundsException
Tentar barrar todas as possibilidades
de erros usando condições (if)
Ocorre quando se tenta acessar um
elemento fora dos limites de um array
Prejudica a legibilidade do código
É pouco eficiente
ClassCastException
Ocorre quando se tenta fazer coerção
equivocada de um objeto
O tratamento de exceção deixa o
código mais legível e eficiente
Permite programas mais robustos e
tolerantes a falhas
NullPointerException
Ocorre quando uma referência null é
usada, quando se espera um objeto
Exemplo: Divide1 (sem TE)
public class Divide1 {
Exemplos com e sem
Tratamento de Exceções
public static int quotient(int numerator, int denominator) {
return numerator / denominator;
}
Pode ocorrer
divisão por zero.
public static void main(String[] args) {
Scanner scanner = new Scanner( System.in );
System.out.print( "Digite o numerador: " );
Pode ser digitado um
int numerator = scanner.nextInt();
valor não numérico.
System.out.print( "Digite o denominador: " );
int denominator = scanner.nextInt();
int result = quotient( numerator, denominator );
System.out.println("Resultado: " + numerator + " / " + denominator +
" = " + result);
}
}
Saídas do Programa
Nenhum problema ocorre
Resultado: 10 / 2 = 5
Divisão por zero
Tipo de erro.
Exception in thread “main”
java.lang.ArithmeticException / by zero
at Divide1.quotient(Divide1.java:10)
at Divide1. main(Divide1.java:22)
Pilha de execução do erro.
Exemplo: Divide2 (com TE)
public class Divide2 {
public static int quotient(int numerator, int denominator)
throws ArithmeticException {
Sinalização da exceção
return numerator / denominator;
}
ArithmeticException. Indica
public static void main(String[] args) {
que o método quotient
Scanner scanner = new Scanner(System.in);
pode lançar tal exceção.
try {
System.out.print("Digite o numerador: ");
int numerator = scanner.nextInt();
System.out.print("Digite o denominador: ");
int denominator = scanner.nextInt();
int result = quotient( numerator, denominator );
System.out.println("Resultado: " + result);
}
catch (InputMismatchException inputMismatchException) {
System.out.println("Devem ser digitados números inteiros.");
}
catch (ArithmeticException arithmeticException) {
System.out.println("Zero é um denominador inválido.");
} }}
Exemplo: Divide2 (com TE)
public class Divide2 {
public static int quotient(int numerator, int denominator)
throws ArithmeticException {
return numerator / denominator;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
Tratadores catch.
System.out.print("Digite o numerador: ");
Indica como cada
int numerator = scanner.nextInt();
System.out.print("Digite o denominador: ");
exceção deve ser tratada.
int denominator = scanner.nextInt();
int result = quotient( numerator, denominator );
System.out.println("Resultado: " + result);
}
catch (InputMismatchException inputMismatchException) {
System.out.println("Devem ser digitados números inteiros.");
}
catch (ArithmeticException arithmeticException) {
System.out.println("Zero é um denominador inválido.");
} }}
Saída do Programa
Tipo digitado não numérico
Exception in thread “main”
java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextInt(Scanner.java:2040)
at java.util.Scanner.nextInt(Scanner.java:2000)
at Divide1.main(Divide1.java:20)
Identificação do provável local do erro.
Classe.método(Arquivo:linha)
Exemplo: Divide2 (com TE)
public class Divide2 {
public static int quotient(int numerator, int denominator)
throws ArithmeticException {
return numerator / denominator;
Região protegida try.
}
Indica que exceções deste
public static void main(String[] args) {
bloco serão tratados.
Scanner scanner = new Scanner(System.in);
try {
System.out.print("Digite o numerador: ");
int numerator = scanner.nextInt();
System.out.print("Digite o denominador: ");
int denominator = scanner.nextInt();
int result = quotient( numerator, denominator );
System.out.println("Resultado: " + result);
}
catch (InputMismatchException inputMismatchException) {
System.out.println("Devem ser digitados números inteiros.");
}
catch (ArithmeticException arithmeticException) {
System.out.println("Zero é um denominador inválido.");
} }}
Saídas do Programa
Nenhum problema ocorre
Resultado: 10 / 2 = 5
Divisão por zero (ArithmeticException)
Zero é um denominador inválido.
Tipo digitado não numérico
(InputMismatchException)
Devem ser digitados números inteiros.
Instrução de Tratamento
Try - Catch - Finally
O tratamento de exceção em Java é
feito pela instrução try-catch-finally
Região protegida (try)
Tratadores (catch)
Finalizador (finally)
As mesmas regras de escopo de
Java são aplicadas
Variáveis locais a um bloco não são
visíveis fora do bloco
Região Protegida (try)
A região protegida (bloco try) inclui o
código que pode lançar uma exceção
Exceções lançadas são tratadas pelos
tratadores (catch)
Nem todos os comandos da região
protegida lançam exceções
Os comandos da região protegida
representam a execução normal do
programa
Tratadores (catch)
Um tratador captura e trata uma exceção
Inicia com a palavra reservada catch
Indica a exceção tratada entre parênteses
Inclui um bloco de comandos para tratar a
exceção
Exemplo: Divide2 (com TE)
public class Divide2 {
public static int quotient(int numerator, int denominator)
throws ArithmeticException {
return numerator / denominator;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
System.out.print("Digite o numerador: ");
int numerator = scanner.nextInt();
Podem lançar
System.out.print("Digite o denominador: ");
InputMismatchException.
int denominator = scanner.nextInt();
int result = quotient( numerator, denominator );
Pode lançar
System.out.println("Resultado: " + result);
ArithmeticException.
}
catch (InputMismatchException inputMismatchException) {
System.out.println("Devem ser digitados números inteiros.");
}
catch (ArithmeticException arithmeticException) {
System.out.println("Zero é um denominador inválido.");
} }}
Exceção Não Capturada
Nem toda exceção lançada pelo programa
necessita ser capturada e tratada
Algumas exceções podem ser ignoradas
Se lançadas e não tratadas, exceções
causam interrupção do programa
Exceções lançadas e engolidas
Pelo menos um tratador catch (ou
finalizador) deve seguir imediatamente
após uma região protegida try
Uma má prática de programação é engolir
exceções.
Tratador vazio (bloco de comandos vazio)
Bloco Finalizador (finally)
São principalmente utilizados para
evitar vazamento de recursos
Devolver conexão com banco de dados
Fechar arquivos abertos
Devolver os recursos de rede, etc.
O bloco finalizador sempre é executado,
independente do lançamento de uma
exceção
Sintaxe de TE
try {
// comandos que lançam exceções
}
catch ( /* Exceção Tratada 1 */ ) {
// comandos que tratam a exceção 1
}
catch ( /* Exceção Tratada 2 */ ) {
// comandos que tratam a exceção 2
}
… // outros tratadores
finally {
// comandos que liberam recursos
}
Hierarquia de Exceções
A hierarquia de exceções de Java
possui centenas de classes
Hierarquia de Exceções
Vide API
Toda exceção deve estender direta ou
indiretamente a classe Throwable
Throwable estende Object
Hierarquia de Exceções
Subclasses de Throwable
Exception
Object
Throwable
Error
...
Exception
ClassCastException
RuntimeException
NullPointerException
IndexOutOfBoundsException
NoSuchElementException
ArrayIndexOutOfBoundsException
InputMismatchException
Representa situações excepcionais que
podem ocorrer nos programas
Podem ser capturadas e tratadas
Error
Representa situações anormais da
máquina virtual Java (JVM)
Não são capturados em aplicativos
Raramente ocorrem
Exceções não Verificadas
Exceções que não precisam ser
sinalizadas, capturadas ou tratadas
O compilador Java não verifica se tais
exceções podem ser lançadas
Exceções não verificadas devem
herdar direta ou indiretamente de
RuntimeException
Error são consideradas exceções não
verificadas
Exceções Verificadas
O compilador impõe a restrição capturar
ou sinalizar para exceções verificadas
Toda exceção que estende Exception e
não estende RuntimeException
Portanto, exceções verificadas
devem ser capturadas (catch) ou
sinalizadas (throws)
Comportamento Polimórfico
Tratadores escritos para capturar
uma superclasse, também tratam
as subclasses
Sinalização de Exceção
Pode-se tratar as subclasses como se
fossem do tipo da superclasse
Opcionalmente, pode-se capturar
individualmente cada exceção
específica
throw
e
throws
Por exemplo, se o tratamento for diferente
Sinalização de Exceção
Cláusula throws
Indica exceções que um método lança
Tais exceções não são tratadas no
corpo do método
Cláusula throws
A cláusula throws sinaliza quais
exceções o método lança
Aparece na assinatura do método depois
da lista de parâmetros
O método pode lançar várias exceções
Comando throw
Usado para lançar uma exceção
Indica que algo errado ocorreu no fluxo
de execução do programa
A lista de exceções deve ser separada
por vírgula
O método também lança exceções de
métodos que o sobrescrevem
Exemplo: Divide2 (com TE)
Comando throw
public class Divide2 {
public static int quotient(int numerator, int denominator)
throws ArithmeticException {
Sinalização da exceção
return numerator / denominator;
}
ArithmeticException. Indica
public static void main(String[] args) {
que o método quotient pode
Scanner scanner = new Scanner(System.in);
lançar tal exceção.
try {
System.out.print("Digite o numerador: ");
int numerator = scanner.nextInt();
System.out.print("Digite o denominador: ");
int denominator = scanner.nextInt();
int result = quotient( numerator, denominator );
System.out.println("Resultado: " + result);
}
catch (InputMismatchException inputMismatchException) {
System.out.println("Devem ser digitados números inteiros.");
}
catch (ArithmeticException arithmeticException) {
System.out.println("Zero é um denominador inválido.");
} }}
É usado para indicar que uma exceção
ocorreu no programa
Lança a exceção (nova ou existente)
Uma nova exceção pode ser criada pelo
comando new
Throw especifica qual exceção será
lançada
Pode ser qualquer objeto de classes que
herdam de Throwable
Exemplo: UsingExceptions
public class UsingExceptions {
public static void main( String[] args ) {
try {
throwException();
Exemplo: UsingExceptions
public class UsingExceptions {
public static void main( String[] args ) {
try {
throwException();
}
}
catch (Exception exception) {
System.err.println("Exception handled in method main");
O bloco finally é executado
independente da exceção
ter sido lançada.
catch (Exception exception) {
System.err.println("Exception handled in method main");
}
}
}
}
public static void throwException() throws Exception {
try {
System.out.println( "Method throwException" );
throw new Exception();
public static void throwException() throws Exception {
try {
System.out.println( "Method throwException" );
throw new Exception();
}
Cria e lança uma
nova exceção.
}
catch (Exception exception) {
System.err.println("Exception handled in method throwException" );
throw exception;
Re-lança a exceção
catch (Exception exception) {
System.err.println("Exception handled in method throwException" );
throw exception;
}
}
capturada.
finally {
System.out.println( "Finally executed in throwException" );
finally {
System.out.println( "Finally executed in throwException" );
}
}
} }
} }
Exemplo: UsingExceptions
public class UsingExceptions {
public static void main( String[] args ) {
try {
throwException();
}
Pode-se usar “System.err” (ao
invés de “System.out”) para
direcionar as mensagens, por
exemplo, para um arquivo de log.
Saída de UsingExceptions
Method throwException
catch (Exception exception) {
System.err.println("Exception handled in method main");
}
}
public static void throwException() throws Exception {
try {
System.out.println( "Method throwException" );
throw new Exception();
Exception handled in method throwException
Finally executed in throwException
}
catch (Exception exception) {
System.err.println("Exception handled in method throwException" );
throw exception;
}
finally {
System.out.println( "Finally executed in throwException" );
}
} }
Exception handled in method main
Modelo de Execução
Término Excepcional
Quando uma exceção é lançada, o fluxo
de execução é desviado para o tratador
Os comandos do bloco try não terminam
Mesmo depois de executar o tratador, o
fluxo não retorna ao bloco try
A execução prossegue para o bloco
finalizador (finally) ou para o comando
imediatamente depois do último tratador
Novas Exceções
Quando um método termina com uma
exceção, nenhum valor é retornado
O método apenas lança a exceção que
deve ser tratada em algum método da
cadeia de chamadas
Se ninguém tratar a exceção, o
programa termina abruptamente
Bibliografia da Aula
Novos tipos de exceção podem ser
criadas
Throwable
Error
DEITEL, H. M.; DEITEL P. J. Java:
Como Programar, 8a. Edição.
Pearson, 2010.
Capítulo 11 Tratamento de Exceções
Exception
RuntimeException
MinhaExcecaoChecada
MinhaExcecaoNaoChecada
Download