Tratamento de Exceções
O tratamento de exceções torna os programas mais robustos. Esta lição cobre o mecanismo de tratamento de exceções do Java.
O que é uma Exceção
Uma exceção é um erro que ocorre durante a execução do programa.
Classificação de Exceções
Throwable
├── Error (erros graves, programa não pode tratar)
│ ├── OutOfMemoryError
│ └── StackOverflowError
└── Exception (exceções, programa pode tratar)
├── Exceções verificadas (devem ser tratadas)
│ ├── IOException
│ └── SQLException
└── Exceções não verificadas (RuntimeException)
├── NullPointerException
├── ArrayIndexOutOfBoundsException
└── NumberFormatException
try-catch
Sintaxe
try {
// Código que pode lançar uma exceção
} catch (TipoExceção nomeVariável) {
// Tratar a exceção
}
Exemplo: Tratamento Básico de Exceções
public class TryCatchDemo {
public static void main(String[] args) {
try {
int result = 10 / 0;
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Erro aritmético: " + e.getMessage());
}
System.out.println("O programa continua");
}
}
Saída:
Erro aritmético: / by zero
O programa continua
Múltiplos Blocos catch
try {
// Código que pode lançar múltiplas exceções
} catch (TipoExceção1 e1) {
// Tratar exceção 1
} catch (TipoExceção2 e2) {
// Tratar exceção 2
} catch (Exception e) {
// Tratar outras exceções
}
Exemplo: Múltiplos catch
public class MultiCatch {
public static void main(String[] args) {
try {
String s = "abc";
int num = Integer.parseInt(s);
int result = 10 / num;
} catch (NumberFormatException e) {
System.out.println("Erro de formato numérico: " + e.getMessage());
} catch (ArithmeticException e) {
System.out.println("Erro aritmético: " + e.getMessage());
} catch (Exception e) {
System.out.println("Outro erro: " + e.getMessage());
}
}
}
try-catch-finally
O bloco finally sempre é executado, ocorra uma exceção ou não.
Sintaxe
try {
// Código que pode lançar uma exceção
} catch (TipoExceção e) {
// Tratar a exceção
} finally {
// Sempre executado
}
Exemplo: finally
public class FinallyDemo {
public static void main(String[] args) {
try {
System.out.println("bloco try");
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("bloco catch");
} finally {
System.out.println("bloco finally");
}
}
}
Saída:
bloco try
bloco catch
bloco finally
Exemplo: Liberação de Recursos
import java.io.*;
public class ResourceDemo {
public static void main(String[] args) {
FileReader reader = null;
try {
reader = new FileReader("test.txt");
// Ler arquivo
} catch (FileNotFoundException e) {
System.out.println("Arquivo não encontrado");
} finally {
// Liberar recurso
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
try-with-resources
Introduzido no Java 7, fecha recursos automaticamente.
Sintaxe
try (TipoRecurso variável = new Recurso()) {
// Usar recurso
} catch (TipoExceção e) {
// Tratar exceção
}
Exemplo: try-with-resources
import java.io.*;
public class TryWithResources {
public static void main(String[] args) {
// Fecha recurso automaticamente
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
String line = reader.readLine();
System.out.println(line);
} catch (IOException e) {
System.out.println("Erro de leitura: " + e.getMessage());
}
// reader fecha automaticamente, não precisa de finally
}
}
throw e throws
throw: Lançar uma Exceção
public static int divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("Não é possível dividir por zero");
}
return a / b;
}
throws: Declarar uma Exceção
public static void readFile(String path) throws FileNotFoundException {
FileReader reader = new FileReader(path);
}
Exemplo: throw e throws
public class ThrowDemo {
public static int divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("Não é possível dividir por zero");
}
return a / b;
}
public static void validateAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Idade inválida: " + age);
}
}
public static void main(String[] args) {
try {
System.out.println(divide(10, 0));
} catch (ArithmeticException e) {
System.out.println(e.getMessage()); // Não é possível dividir por zero
}
try {
validateAge(-5);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage()); // Idade inválida: -5
}
}
}
Exceções Personalizadas
Passos
- Estender Exception ou RuntimeException
- Fornecer construtores
Exemplo: Exceção Personalizada
// Classe de exceção personalizada
public class InsufficientBalanceException extends Exception {
private double balance;
private double amount;
public InsufficientBalanceException(double balance, double amount) {
super("Saldo insuficiente: " + balance + ", saque: " + amount);
this.balance = balance;
this.amount = amount;
}
public double getBalance() {
return balance;
}
public double getAmount() {
return amount;
}
}
// Usando exceção personalizada
public class BankAccount {
private double balance;
public BankAccount(double balance) {
this.balance = balance;
}
public void withdraw(double amount) throws InsufficientBalanceException {
if (amount > balance) {
throw new InsufficientBalanceException(balance, amount);
}
balance -= amount;
System.out.println("Saque bem-sucedido, saldo: " + balance);
}
public static void main(String[] args) {
BankAccount account = new BankAccount(1000);
try {
account.withdraw(500); // Saque bem-sucedido, saldo: 500.0
account.withdraw(800); // Lança exceção
} catch (InsufficientBalanceException e) {
System.out.println(e.getMessage());
System.out.println("Saldo: " + e.getBalance());
System.out.println("Saque: " + e.getAmount());
}
}
}
Exceções Comuns
| Exceção | Descrição | Causa |
|---|---|---|
NullPointerException |
Ponteiro nulo | Chamar método em objeto nulo |
ArrayIndexOutOfBoundsException |
Índice de array fora dos limites | Acessar índice inexistente |
NumberFormatException |
Erro de formato numérico | Conversão de string para número falhou |
ClassCastException |
Erro de conversão de tipo | Tipo de downcast incompatível |
ArithmeticException |
Erro aritmético | Dividir por zero |
FileNotFoundException |
Arquivo não encontrado | Caminho de arquivo incorreto |
IOException |
Erro de IO | Falha na leitura/escrita de arquivo |
Princípios de Tratamento de Exceções
| Princípio | Descrição |
|---|---|
| Exceções específicas primeiro | Capture exceções específicas antes das gerais |
| Não ignore exceções | Pelo menos registre em log |
| Use finally para recursos | Ou use try-with-resources |
| Não use exceções para controle de fluxo | Exceções são para erros, não para controle de fluxo |
❓ Perguntas Frequentes
P: Qual é a diferença entre Error e Exception? R: Error é um problema grave que o programa não pode tratar. Exception é um problema que o programa pode capturar e tratar.
P: Qual é a diferença entre exceções verificadas e não verificadas? R: Exceções verificadas devem ser tratadas (try-catch ou throws). Exceções não verificadas não precisam ser tratadas.
P: Quando devo criar exceções personalizadas? R: Quando precisar distinguir tipos de exceções de negócios, como saldo insuficiente ou usuário não encontrado.
📖 Resumo
- Exceções são erros que ocorrem durante a execução do programa
- try-catch captura exceções, finally libera recursos
- throw lança exceções, throws declara exceções
- try-with-resources fecha recursos automaticamente
- Exceções personalizadas estendem Exception ou RuntimeException
📝 Exercícios
- Tratamento de exceções: Escreva um método para ler um arquivo, tratando arquivo não encontrado e erros de leitura
- Exceção personalizada: Defina uma exceção AgeOutOfBoundsException para validação de idade
- Gerenciamento de recursos: Use try-with-resources para implementar cópia de arquivo
Próxima Lição
Na próxima lição, aprenderemos sobre Prática: OOP — aplicando conhecimentos de orientação a objetos.



