Mi sono imbattuto in codice simile a questo:
void run() {
try {
doSomething();
} catch (Exception ex) {
System.out.println("Error: " + ex);
throw ex;
}
}
void doSomething() {
throw new RuntimeException();
}
Questo codice mi sorprende perché sembra che il run()metodo sia in grado di lanciare un Exception, dal momento che lo cattura Exceptione lo ricodifica, ma il metodo non è dichiarato da lanciare Exceptione apparentemente non è necessario. Questo codice viene compilato correttamente (almeno in Java 11).
La mia aspettativa sarebbe che avrei dovuto dichiarare throws Exceptionnel run()metodo.
Ulteriori informazioni
In modo simile, se doSomethingviene dichiarato di buttare IOExceptionallora solo IOExceptionbisogno di essere dichiarato nel run()-Metodo, anche se Exceptionviene catturato e rilanciati.
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 ...
}
Domanda
Java di solito ama la chiarezza, qual è la ragione di questo comportamento? È sempre stato così? Cosa nelle specifiche del linguaggio Java consente al run()metodo di non dover dichiarare throws Exceptionnei frammenti di codice sopra? (Se lo aggiungessi, IntelliJ mi avverte che Exceptionnon viene mai lanciato).
-source 1.6flag genera un errore di compilazione come previsto. La compilazione con compatibilità sorgente 7 non non aumentare l'errore di compilazione
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: mi sono imbattuto in casi in cui il compilatore Eclipse era più indulgente.