1. ホーム
  2. java

[解決済み] Java unreachable catch block コンパイラーエラー

2022-02-15 06:02:27

質問

なぜJavaでは Exception をスローしていないのに、そのサブクラスをキャッチすることができません("unchecked".を除きます)。 RuntimeException とそのサブクラス)。コード例

class Test {
    public static void main(String[] args) {
        try {
            // do nothing
        } catch (Exception e) {
            // OK           
        }

        try {
            // do nothing
        } catch (IOException e) {
               // COMPILER ERROR: Unreachable catch block for IOException.
               //This exception is never thrown from the try statement body
        }       
    }
}

何かアイデアはありますか?

解決方法は?

A RuntimeException が投げられる可能性があります。 任意の のコードです。言い換えれば、コンパイラはどのようなコードがこれを投げるかを容易に予測することはできません。A RuntimeException が引っかかることがあります。 catch(Exception e) ブロックを作成します。

IOException しかし、これはチェックされた例外であり、これを投げると宣言されたメソッドコールだけがこれを投げることができます。コンパイラは、これを投げるように宣言されたメソッドコールがない限り、この例外が発生することはあり得ないと(合理的に)確信することができるのです。

Javaコンパイラは、tryブロック内にまったくコードがない、という状況を考慮しません。 合理的 シナリオでは 可能性がある チェックされていない例外を投げる可能性があります。

から セクション14.21 の「JLS」を参照してください。

キャッチブロックCは、以下の両方が真であれば到達可能である。

  • tryブロック内のある式またはthrow文は到達可能であり、その型がcatch句Cのパラメータに割り当て可能な例外を投げることができます(式は、それを含む最も内側の文が到達可能である場合に到達可能とみなされます)。
  • try文の中に、Cのパラメータの型がAのパラメータの型と同じかサブクラスであるような先行するキャッチブロックAが存在しない。

を認識する必要があります。 いいえ この場合、try ブロックの中にある式は、まだ到達不可能な catch 節に見えます。

EDIT: コメントにある通りです。 セクション14.20 には、これが含まれています。

を指定した場合、コンパイルエラーとなります。 catch 節はチェックされた例外タイプ E1 しかし、チェックされた例外タイプは存在しない E2 がすべて成立するような

  • E2 <。 E1
  • try ブロックに対応する catch を投げることができます。 E2
  • 先行なし catch のブロックは、try 文の直後にある E2 のスーパータイプ、または E2 .

ない限り E1 はクラスExceptionです。

ということのようですね。 実際に しかし、14.21の到達不能なキャッチブロックに関しては、仕様が明確ではありません。