Exceções
Em Java, “um evento que ocorre durante a execução de um programa que interrompe o fluxo normal de instruções” é chamado de exceção. Geralmente, é um evento inesperado ou indesejado que pode ocorrer em tempo de compilação ou em tempo de execução no código da aplicação. As exceções Java podem ser de vários tipos e todos os tipos de exceção são organizados em uma hierarquia fundamental.
Hierarquia de exceções em Java
A hierarquia de exceções em Java é organizada da seguinte forma:
- Throwable: A classe raiz de todas as exceções e erros em Java. Ela tem duas subclasses principais:
- Exception: Representa problemas que um programa pode querer capturar e tratar.
- Error: Representa problemas graves que normalmente o programa não deve tentar capturar (por exemplo, OutOfMemoryError).
- Tipos de Exception:
- Exceções Verificadas (Checked Exceptions): Exceções que devem ser tratadas pelo programa, usando blocos try-catch ou declarando com throws. São verificadas pelo compilador. Exemplo: IOException, SQLException.
- Exceções Não Verificadas (Unchecked Exceptions): Exceções que não são verificadas pelo compilador. São subclasses de RuntimeException, como NullPointerException, ArrayIndexOutOfBoundsException.

Exceções verificadas e não verificadas
Exceções verificadas (checked exceptions)
- São verificadas em tempo de compilação.
- O programador é obrigado a tratá-las ou declará-las com throws.
- Exemplo: IOException, SQLException.
Exceções não verificadas (unchecked exceptions)
- São verificadas em tempo de execução.
- O programador não é obrigado a tratá-las.
- Exemplo: NullPointerException, ArithmeticException.
Tratamento de exceções
O tratamento de exceções em Java é realizado usando os blocos try – catch – finally e throw.
Sintaxe:
try {
//Bloco de código que pode gerar uma exceção
} catch (TipoExcecao e){
//Bloco de código que trata a exceção
} [finally {
//Bloco de código que será sempre executado
}]
O bloco try-catch-finally pode tratar uma ou várias exceções, declarando um bloco catch para cada exceção tratada.
O bloco finally é opcional e, se existir, só pode ocorrer uma vez, no final do bloco try-catch. Este bloco é sempre executado quer haja uma exceção quer não. Normalmente, este bloco é usado para libertar recursos, como por exemplo, fechar ficheiros ou conexões a uma base de dados.
Exemplo:
import java.io.*;
public class ReadFile {
public static void main(String[] args) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("ficheiro.txt"));
String line = reader.readLine();
System.out.println(line);
} catch (IOException e) {
System.out.println("Erro ao ler o ficheiro.");
} finally {
try {
if (reader != null) {
reader.close(); // O recurso é sempre fechado, mesmo se ocorrer uma exceção
}
} catch (IOException e) {
System.out.println("Erro ao fechar o ficheiro.");
}
}
}
}
Declarar exceções com throws
Quando, num bloco de código de um método, houver a eventualidade de esse código gerar uma exceção, o método pode fazer uma de duas coisas:
- Tratar a exceção com try-catch.
- Declarar a exceção com a palavra reservada throws de forma a que o código que chama o método trate a exceção:
A sintaxe de throws é a seguinte:
public nomeMetodo() throws TipoExcecao1[,..., TipoExcecaoN] {
//código que pode gerar uma exceção
}
Exemplo:
public void lerFicheiro() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("ficheiro.txt"));
String line = reader.readLine();
System.out.println(line);
}
public void mostraDadosFicheiro(){
try{
lerFicheiro();
catch(IOException ex){
System.out.println("Erro na leitura do ficheiro");
}
}
No exemplo acima, o método lerFicheiro() não trata a exceção IOException mas “lança-a” para o método que o chamou. O método mostraDadosFicheiro() pode tratar a exceção ou “lança-la” a para o método que o chama.
Exceções personalizadas
O programador pode criar as suas próprias exceções. Fá-lo criando uma classe que seja subclasse de Exception. Depois, usa a instrução throw para disparar a exceção :
class NotaInvalidaException extends Exception {
public NotaInvalidaException(String msg) {
super(msg); //passa a mensagem para o construtor de Exception
}
}
class Main {
public validaNota(int nota){
if(nota < 0 || nota > 20 ){
throw new NotaInvalidaException("Nota inválida: deve ser entre 0 e 20");
}
}
public void obterNota() {
try{
validaNota(17);
}catch(NotaInvalidaException ex){
System.out.println(ex.getMessage());
}
}
}
