CodeGym /Cursos /JAVA 25 SELF /Hierarquia de exceções em Java

Hierarquia de exceções em Java

JAVA 25 SELF
Nível 24 , Lição 0
Disponível

1. Classe Throwable: a raiz de todas as exceções

Agora vamos detalhar como o sistema de exceções no Java é estruturado: o que é Throwable, em que Exception e Error diferem e o que significam as exceções “verificadas” e “não verificadas”. Este é o fundamento para um tratamento de erros adequado nos seus programas.

No Java, todas as exceções e erros são objetos que herdam da classe java.lang.Throwable.
Throwable é o “ancestral” de toda a hierarquia de tratamento de problemas no Java.

Esquematicamente:

Throwable
├── Exception
└── Error

Throwable é a classe base de tudo o que pode ser “lançado” (throw) e “capturado” (catch) em Java. Não se usa essa classe diretamente — ela serve de base para tipos de erro mais específicos.

Exception — para erros “normais”

Exception é a classe base para todas as exceções que podem surgir no programa e que você pode e deve tratar. São erros operacionais: problemas com arquivos, rede, entrada/saída, erros do usuário etc. A maioria dos seus try-catch trabalhará justamente com subclasses de Exception.

Exemplos:

  • IOException — erro ao trabalhar com arquivos ou rede.
  • SQLException — erro ao trabalhar com banco de dados.
  • FileNotFoundException — arquivo não encontrado.

Error — para erros fatais da JVM

Error é a classe base para erros que ocorrem no nível da máquina virtual Java (JVM). Normalmente são falhas críticas que o programa não pode e não deve tratar. Se ocorrer um Error — é bem provável que o aplicativo não consiga continuar executando.

Exemplos:

  • OutOfMemoryError — a memória acabou.
  • StackOverflowError — estouro de pilha (por exemplo, por recursão infinita).
  • NoClassDefFoundError — a classe necessária não foi encontrada.

Importante:
Capturar e tratar Error — quase sempre é uma má ideia. Não são erros do seu programa, mas falhas do ambiente de execução.

2. Checked vs Unchecked exceptions: o que isso significa?

No Java, todas as exceções se dividem em dois grandes grupos:

Exceções verificadas (Checked)

O que são? Exceções que o compilador obriga você a tratar ou a propagar explicitamente.

Quando ocorrem? Geralmente estão ligadas a recursos externos: arquivos, rede, bancos de dados, entrada do usuário.

Como tratar? Você deve envolver o código com try-catch ou adicionar throws à assinatura do método.

Exemplos: IOException, SQLException, FileNotFoundException

Exemplo:

public void readFile(String path) throws IOException {
    FileReader reader = new FileReader(path); // pode lançar IOException
    // ...
}

Se você não tratar nem propagar — o programa não vai compilar!

Exceções não verificadas (Unchecked)

O que são? Exceções que não exigem tratamento obrigatório pelo compilador.

Quando ocorrem? Geralmente são erros na lógica do programa: divisão por zero, acesso fora dos limites do array, acesso a null.

Como tratar? Pode capturar, mas não é obrigatório. É melhor prevenir esses erros com verificações.

Onde na hierarquia? Todas herdam de RuntimeException.

Exemplos: NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException, ArithmeticException

Exemplo:

int[] arr = {1, 2, 3};
System.out.println(arr[10]); // ArrayIndexOutOfBoundsException

O compilador não exige que você capture essa exceção — mas o programa falhará quando o erro ocorrer.

3. Toda a hierarquia em uma figura

graph TD
    Throwable --> Error
    Throwable --> Exception
    
    Exception --> RuntimeException
    Exception --> CheckedExceptions["(outras exceções verificadas)"]
    
    Error --> OutOfMemoryError
    Error --> StackOverflowError
    
    RuntimeException --> NullPointerException
    RuntimeException --> IndexOutOfBoundsException
    RuntimeException --> IllegalArgumentException

    %% Estilos
    style Throwable fill:#ffa64d,color:#000
    style Exception fill:#ffa64d,color:#000
    style CheckedExceptions fill:#ffa64d,color:#000
    
    style Error fill:#ff4d4d,color:#fff
    style OutOfMemoryError fill:#ff4d4d,color:#fff
    style StackOverflowError fill:#ff4d4d,color:#fff
    
    style RuntimeException fill:#4dff88,color:#000
    style NullPointerException fill:#4dff88,color:#000
    style IndexOutOfBoundsException fill:#4dff88,color:#000
    style IllegalArgumentException fill:#4dff88,color:#000

Tabela: diferenças principais

Grupo Classe pai Exige tratamento? Exemplos
Checked Exception
Exception
Sim
IOException, SQLException
Unchecked
RuntimeException
Não
NullPointerException, IndexOutOfBoundsException
Error
Error
Não
OutOfMemoryError, StackOverflowError

4. Como isso aparece no código?

Checked Exception: exemplo com arquivos

import java.io.*;

public class FileDemo {
    public static void main(String[] args) {
        try {
            FileReader reader = new FileReader("nofile.txt"); // FileNotFoundException (checked)
            int data = reader.read();
            System.out.println(data);
            reader.close();
        } catch (IOException e) {
            System.out.println("Erro ao trabalhar com arquivo: " + e.getMessage());
        }
    }
}

O compilador vai obrigar você a tratar IOException!

Unchecked Exception: exemplo de divisão por zero

public class ExceptionDemo {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        int c = a / b; // ArithmeticException (unchecked)
        System.out.println("Resultado: " + c);
    }
}

O compilador não exige tratamento, mas o programa vai falhar.

5. Por que precisamos da hierarquia de exceções?

  • Flexibilidade no tratamento: É possível capturar erros específicos (FileNotFoundException) ou grupos inteiros (IOException ou Exception).
  • Reutilização de código: Permite tratar centralizadamente erros de um mesmo tipo.
  • Código mais limpo: A lógica principal não fica poluída com verificações para cada detalhe.

Exemplo:

try {
    // código perigoso
} catch (FileNotFoundException e) {
    System.out.println("Arquivo não encontrado!");
} catch (IOException e) {
    System.out.println("Erro de E/S!");
} catch (Exception e) {
    System.out.println("Algo deu errado: " + e.getMessage());
}

6. Erros típicos ao trabalhar com exceções

Erro nº 1: Ignorar exceções. Escrever catch (Exception e) {} — é ruim! Você perde informações sobre a causa do erro.

Erro nº 2: Capturar demais. catch (Exception e) captura tudo, até o que você não esperava. É melhor capturar apenas as exceções que você sabe tratar.

Erro nº 3: Capturar Errors. Não capture Error a menos que você esteja escrevendo código de baixo nível. Esses são problemas da JVM, não do seu programa.

Erro nº 4: Não distinguir checked e unchecked. Nem todas as exceções são iguais! As checked exigem tratamento (Exception); as unchecked — não (RuntimeException e suas subclasses).

Erro nº 5: Não adicionar informações às exceções. Se você cria suas próprias exceções — sempre adicione uma mensagem informativa.

1
Tarefa
JAVA 25 SELF, nível 24, lição 0
Bloqueado
Desvendando os mistérios das exceções: Hierarquia dos Pais
Desvendando os mistérios das exceções: Hierarquia dos Pais
1
Tarefa
JAVA 25 SELF, nível 24, lição 0
Bloqueado
Quem está no comando? Diferença entre exceções e erros
Quem está no comando? Diferença entre exceções e erros
1
Tarefa
JAVA 25 SELF, nível 24, lição 0
Bloqueado
Sistema de alertas: Ameaças verificadas e não verificadas
Sistema de alertas: Ameaças verificadas e não verificadas
1
Tarefa
JAVA 25 SELF, nível 24, lição 0
Bloqueado
O robô-bibliotecário e seus "planos de resgate"
O robô-bibliotecário e seus "planos de resgate"
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION