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 Exception
e lo ricodifica, ma il metodo non è dichiarato da lanciare Exception
e apparentemente non è necessario. Questo codice viene compilato correttamente (almeno in Java 11).
La mia aspettativa sarebbe che avrei dovuto dichiarare throws Exception
nel run()
metodo.
Ulteriori informazioni
In modo simile, se doSomething
viene dichiarato di buttare IOException
allora solo IOException
bisogno di essere dichiarato nel run()
-Metodo, anche se Exception
viene 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 Exception
nei frammenti di codice sopra? (Se lo aggiungessi, IntelliJ mi avverte che Exception
non viene mai lanciato).
-source 1.6
flag 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.