Ich bin auf Code gestoßen, der ungefähr so aussieht:
void run() {
try {
doSomething();
} catch (Exception ex) {
System.out.println("Error: " + ex);
throw ex;
}
}
void doSomething() {
throw new RuntimeException();
}
Dieser Code überrascht mich, weil es so aussieht, als ob die run()
-Methode in der Lage ist, ein zu werfen Exception
, da es es fängt Exception
und dann erneut wirft, aber die Methode ist nicht zum Werfen deklariert Exception
und muss es anscheinend nicht sein. Dieser Code wird einwandfrei kompiliert (zumindest in Java 11).
Meine Erwartung wäre, dass ich throws Exception
in der run()
Methode deklarieren müsste .
Zusatzinformation
In ähnlicher Weise muss, wenn doSomething
zum Werfen deklariert wird, IOException
nur IOException
in der Methode deklariert werden run()
, obwohl Exception
es gefangen und erneut geworfen wird.
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 ...
}
Frage
Java mag normalerweise Klarheit. Was ist der Grund für dieses Verhalten? War es schon immer so? Was in der Java-Sprachspezifikation erlaubt es der run()
Methode, nicht throws Exception
in den obigen Codefragmenten zu deklarieren ? (Wenn ich es hinzufügen würde, warnt mich IntelliJ, dass Exception
es nie geworfen wird).
-source 1.6
Flag führt erwartungsgemäß zu einem Kompilierungsfehler. Das Kompilieren mit
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
- Ich bin auf Fälle gestoßen, in denen der Eclipse-Compiler milder war.