Eu me deparei com código parecido com isto:
void run() {
try {
doSomething();
} catch (Exception ex) {
System.out.println("Error: " + ex);
throw ex;
}
}
void doSomething() {
throw new RuntimeException();
}
Esse código me surpreende porque parece que o run()
-method é capaz de lançar um Exception
, já que ele captura Exception
e o repete novamente, mas o método não está declarado para lançar Exception
e aparentemente não precisa ser. Esse código compila perfeitamente (pelo menos no Java 11).
Minha expectativa seria que eu tivesse que declarar throws Exception
no run()
método
Informação extra
De maneira semelhante, se doSomething
for declarado como lançado, IOException
ele só IOException
precisará ser declarado no run()
método-, mesmo que Exception
seja capturado e reapresentado.
void run() throws IOException {
try {
doSomething();
} catch (Exception ex) {
System.out.println("Error: " + ex);
throw ex;
}
}
void doSomething() throws IOException {
// ... whatever code you may want ...
}
Questão
Java geralmente gosta de clareza, qual é a razão por trás desse comportamento? Sempre foi assim? O que na especificação da linguagem Java permite que o run()
método não precise declarar throws Exception
nos trechos de código acima? (Se eu adicionar, o IntelliJ me avisa que Exception
nunca é lançado).
-source 1.6
sinalizador gera um erro de compilação conforme o esperado. Compilando com compatibilidade de origem 7 que não elevar o erro de compilação
In detail, in Java SE 7 and later, when you declare one or more exception types in a catch clause, and rethrow the exception handled by this catch block, the compiler verifies that the type of the rethrown exception meets the following conditions : 1. 1. The try block is able to throw it. 2. There are no other preceding catch blocks that can handle it. 3. It is a subtype or supertype of one of the catch clause's exception parameters.
javac
- eu estive executando em casos em que o compilador Eclipse era mais branda.