Domínio 4 — Exceções
TL;DR
Este domínio cobra a mecânica de tratamento de erros do Java: a hierarquia de
Throwable, a distinção entre checked e unchecked, o fluxo exato detry/catch/finally, otry-with-resources(com seus suppressed exceptions e ordem reversa de fechamento) e as regras dethrowsna sobrescrita. A prova adora pegadinhas de ordem de execução —returnnofinally, ordem declose(), multi-catch que não compila. Domine o fluxo e o controle, não decore casos isolados.
Títulos oficiais
- 1Z0-830 (Java 21): Handling Exceptions
- 1Z0-831 (Java 25): Implementing Exception Handling in Java Applications
O que a Oracle cobra
- Hierarquia —
Throwableé a raiz; abaixo dela,Error(falhas do ambiente, não se tratam) eException. Dentro deException, háRuntimeExceptione suas filhas (unchecked) e o restante (checked). - Checked vs unchecked — checked obrigam tratamento ou propagação via
throws(verificado em compilação); unchecked (RuntimeExceptioneError) não obrigam nada. Saber classificar uma exceção dada é cobrança recorrente. - try/catch/finally — ordem de execução, multi-catch com
|, exception chaining (new RuntimeException("msg", causa)egetCause()). - try-with-resources —
AutoCloseable/Closeable, suppressed exceptions, ordem declose(). - throws — propagação de exceções pela pilha e regras de overriding (sobrescrita não pode ampliar o contrato de checked).
- Custom exceptions — criar subclasses de
ExceptionouRuntimeExceptioncom construtores que repassam mensagem e causa. - Assertions —
assert cond : msg;, habilitação via-ea. Raro, mas pode aparecer.
Mapa de revisão
- Exceções e tratamento de erros (G1) — toda a mecânica.
Pegadinhas deste domínio
(1) return no try e return no finally — o do finally vence. O finally sempre executa, e se ele tem seu próprio return, descarta o valor que o try ia retornar:
public int foo() {
try {
return 1;
} finally {
return 2; // retorna 2 — o return do try é descartado
}
}(2) try-with-resources fecha na ORDEM REVERSA da declaração. O último recurso aberto é o primeiro a ser fechado:
try (var a = abrir("A"); var b = abrir("B")) {
// ...
} // fecha B primeiro, depois A(3) Multi-catch não pode listar exceções relacionadas por herança. Se uma já é subclasse da outra, há redundância e o código NÃO compila:
try {
// ...
} catch (IOException | FileNotFoundException e) { // ERRO de compilação:
// FileNotFoundException já é subclasse de IOException
}(4) Sobrescrita não pode ADICIONAR checked exception. O método que sobrescreve pode declarar as mesmas checked, uma subclasse delas, menos exceções ou nenhuma — mas nunca uma checked nova/mais ampla:
class Pai {
void m() throws IOException {}
}
class Filho extends Pai {
@Override
void m() throws FileNotFoundException {} // OK: subclasse de IOException
// void m() throws Exception {} // NÃO compila: amplia o contrato
}(5) Suppressed exceptions — a do close() fica suprimida se o corpo já lançou. Se o bloco try lança e o close() também lança, a do corpo “vence” (é propagada) e a do close() vira suppressed, recuperável via getSuppressed():
try (var r = recursoQueFalhaAoFechar()) {
throw new RuntimeException("erro no corpo"); // esta propaga
} // exceção do close() fica suprimida — e.getSuppressed()[0]Para o catálogo completo
Mais armadilhas de fluxo e compilação estão reunidas em catálogo de pegadinhas.
Em entrevista
Você não reivindica a credencial, mas o vocabulário aparece naturalmente ao falar de robustez:
“I lean on try-with-resources so every
AutoCloseableis closed in reverse order, and I checkgetSuppressed()when a failure duringclose()could mask the real error from the body.”
Ou, sobre controle de fluxo:
“A
returninfinallysilently overrides the one intry, so I keepfinallyfree of control-flow statements.”
Vocabulário PT | EN:
- exceção verificada → checked exception
- exceção não verificada → unchecked exception
- exceção suprimida → suppressed exception
- encadeamento de exceções → exception chaining
- propagação → propagation
- sobrescrita → overriding