私は次のようなコードに遭遇しました:
void run() {
try {
doSomething();
} catch (Exception ex) {
System.out.println("Error: " + ex);
throw ex;
}
}
void doSomething() {
throw new RuntimeException();
}
このコードは私を驚かせます。- methodはそれをキャッチしてから再スローするため、をスローrun()
できるように見えますが、メソッドがスローするように宣言されておらず、明らかにそうである必要はないからです。このコードは問題なくコンパイルされます(少なくともJava 11では)。Exception
Exception
Exception
私の予想ではthrows Exception
、- run()
メソッドで宣言する必要があるでしょう。
追加情報
同様に、if doSomething
がスローするように宣言されている場合、キャッチされて再スローされても、-methodで宣言するIOException
だけで済みIOException
ます。run()
Exception
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 ...
}
質問
Javaは通常、明快さを好みますが、この動作の背後にある理由は何ですか?いつもこんな感じでしたか?Java言語仕様の中で、上記のコードスニペットでrun()
メソッドが宣言する必要のないものは何throws Exception
ですか?(追加すると、IntelliJ Exception
はスローされないことを警告します)。
-source 1.6
フラグを使用してコンパイルすると、予想どおりにコンパイルエラーが発生します。ソース互換性7でコンパイルしてもコンパイルエラーは発生しません
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
-私はEclipseコンパイラーの方が寛大な場合に遭遇しています。