Checked/unchecked exceptions

Eai galera, estou com umas dúvidas sobre exceptions…

  • Qual é a diferença entre checked e unchecked exceptions?
  • O que é a RunTimeException?
  • A cláusula throws joga a exception para o método que chamou o segundo método(este que disparou a exception)? Sendo assim a exception pode ser tratada no primeiro método, dentro do catch?
  • Checked: O método (ou construtor) que lança checked exceptions deve obrigatoriamente declarar isso em sua assinatura. Quem chama esse método que declara lançar checked exceptions, deve obrigatoriamente trata-las. Tratar significa:

    1. Capturar com try/catch;
    2. Declarar na assinatura do método e relançar a exception para quem o chamou.
  • Unchecked: São problemas (não só exceptions) que não precisam ser tratados obrigatoriamente. Geralmente (ou sempre) indicam um erro de programação. São subclasses de RunTimeException ou Error.

Isso é só uma convenção adotada pelo compilador. Durante a execução, você pode capturar unchecked exceptions normalmente. Você só não é obrigado a tratar tudo, mas apenas as checked exceptions.

Essa imagem mostra a hierarquia de problemas que podem acontecer durante a execução de um programa.

Um exemplo de unchecked exception é a NumberFormatException, que acontece quando você tenta converter uma String inválida para um formato numérico. Assim:

int x = Integer.parseInt("1a");

Você não é obriagdo, mas pode capturar essa exceção:

try {
    int x = Integer.parseInt("1a");
} catch (NumberFormatException e) {
    ...
}

Já o contrário, uma checked exception, deve ser obrigatoriamente tratada. O método sleep lança uma InterruptedException, que herda diretamente de Exception, e portanto é checked.

public static void main(String[] args) {
    TimeUnit.SECONDS.sleep(1); // erro de compilação, checked exception deve ser capturada ou relançada no throws
}

Para resolver:

public static void main(String[] args) throws InterruptedException { // ou qualquer superclasse de InterruptedException
    TimeUnit.SECONDS.sleep(1);
}

ou:

public static void main(String[] args) {
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) { // ou qualquer superclasse de InterruptedException
        ...
    }
}

Se você faz isso:

try {
    ...
catch (Throwable t) {
    ...
}

Esse catch vai pegar absolutamente todo e qualquer problema que acontecer durante a execução do try.

2 curtidas

Bela aula de Exceptions. hahaha

Muito obrigado cara, é sempre muito bom receber uma resposta completa assim. Isso me incentiva a continuar estudando!!! muuuuito grato :wink::grin::grin: