Sobes.tech
Junior

Como são tratados os erros em Java e como trabalhar com eles?

sobes.tech IA

Resposta da IA

Em Java, os erros são tratados usando o mecanismo de exceções. As exceções representam eventos que interrompem o fluxo normal de execução do programa. Existem dois tipos de exceções: Exceções Verificadas (Checked Exceptions) e Exceções Não Verificadas (Unchecked Exceptions).

Exceções Verificadas:

  • Herdam de java.lang.Exception (exceto RuntimeException).
  • Devem ser tratadas (usando try-catch) ou declaradas na assinatura do método (usando throws).
  • Representam erros que podem ocorrer em condições normais (por exemplo, IOException, FileNotFoundException).

Exceções Não Verificadas:

  • Herdam de java.lang.RuntimeException ou java.lang.Error.
  • Não requerem tratamento ou declaração obrigatória.
  • Representam erros que frequentemente indicam erros lógicos no código ou estados anormais do ambiente de execução (por exemplo, NullPointerException, ArrayIndexOutOfBoundsException).

Tratamento de exceções:

Para tratar exceções, usam-se blocos try-catch-finally:

  • try: Bloco de código que pode gerar uma exceção.
  • catch: Bloco de código que é executado se uma exceção do tipo especificado ocorrer no try. Pode haver vários blocos catch para diferentes tipos de exceções.
  • finally: Bloco de código que é sempre executado, independentemente de uma exceção ocorrer ou não. Frequentemente usado para liberar recursos (por exemplo, fechar ficheiros, ligações).
try {
    // Código que pode lançar exceção
    int result = 10 / 0; // Exemplo: ArithmeticException
} catch (ArithmeticException e) {
    // Tratamento de ArithmeticException
    System.err.println("Erro de divisão por zero: " + e.getMessage());
    // Pode registar o erro, mostrar mensagem ao utilizador, etc.
} catch (Exception e) {
    // Tratamento de qualquer outra exceção não previamente tratada
    System.err.println("Ocorreu um erro geral: " + e.getMessage());
} finally {
    // Código que sempre é executado
    System.out.println("Bloco finally executado.");
}

Propagação de exceções:

Um método pode declarar que pode gerar uma exceção específica usando a palavra-chave throws:

public void readFile(String filePath) throws FileNotFoundException, IOException {
    // Código para ler ficheiro
    // Se o ficheiro não for encontrado, pode lançar-se FileNotFoundException (subclasse de IOException)
    FileReader fr = new FileReader(filePath);
    // Se ocorrer erro de entrada/saída, pode lançar-se IOException
    // ...
}

O método que chama deve tratar esta exceção (try-catch) ou também declará-la com throws.

Criação de exceções próprias:

Pode criar classes de exceções personalizadas herdando de Exception (para Exceções Verificadas) ou RuntimeException (para Exceções Não Verificadas).

public class MyCustomException extends Exception {
    public MyCustomException(String message) {
        super(message);
    }
}

Uso:

public void processData(int value) throws MyCustomException {
    if (value < 0) {
        throw new MyCustomException("O valor não pode ser negativo");
    }
    // Processamento de dados
}

Principais classes de exceções (hierarquia):

  • java.lang.Throwable (classe base para todos os erros e exceções)
    • java.lang.Error (para problemas graves que geralmente não são tratados pelo programa, por exemplo, OutOfMemoryError)
    • java.lang.Exception (para exceções que o programa pode tratar)
      • java.lang.RuntimeException (Unchecked Exceptions)
        • NullPointerException
        • ArrayIndexOutOfBoundsException
        • ArithmeticException
        • etc.
      • Outras subclasses de Exception (Checked Exceptions)
        • IOException
        • FileNotFoundException
        • SQLException
        • etc.

Trabalhar com erros envolve compreender essa hierarquia, escolher o tipo de exceção adequado (ao criar as próprias), usar eficazmente try-catch-finally para tratar e propagar exceções, bem como fazer logging de erros para depuração.