0
public class UnrechableCode {
        public static void main (String args[])
        {
            UnrechableCode uc=new UnrechableCode();
            try
            {
               System.out.println(1/0);
            }
            catch(Exception e)
            {
                System.out.print("Inside Catch");
                return ;
            }
            finally
            {
                 System.out.println("Inside Finally");
                 //return;
            }
            System.out.println("TEST");
        }
}

上記のコードで、Catch から return ステートメントを削除すると、finally ブロックの後のステートメントは実行されませんが、パーサーによって到達可能です。同じシナリオで、finally ブロックに return を書き込むと、同じステートメントにパーサーが到達できないため、前のケースでステートメントがパーサーに到達できる場合、ステートメントが実行されないのはなぜですか?

4

1 に答える 1

2

Java コンパイラには、プログラム内の特定のコード行に到達できるかどうかを予測する機能が限られています。この事実は、Java の設計者の責任ではありません。汎用言語の考えられるすべてのプログラムの動作をそれほど完全に予測することは不可能であることは証明済みの事実です。Java の設計者ができる唯一の選択肢は、コンパイラのこの機能をどれだけ制限するかということです。

Java に "unreachable statement" コンパイラ エラーがあるのはなぜですか?を参照してください。 コンパイラがこの機能を持っている理由、「到達不能コード」をエラーと見なす理由、および「到達不能コード」として (比較的簡単に) 検出された可能性のあるいくつかのものが「到達不能コード」と見なされない理由について説明します。コンパイラによるエラー。

あなたの特定のケースでは、1/0常に例外をスローするという事実と、例外をキャッチするブロックreturn内にあるという事実catchにより、プログラムの実行が出力に「TEST」を書き込むことができなくなります。ただし、Java コンパイラは1/0、到達不能なコードを探す場合などにスローされる例外を考慮しません。したがって、tryブロックを実行し、例外をスローせcatch(ブロック内のコードを実行しなかった)、ブロックを実行し、finally ブロックの後のコードを実行する可能性のある制御パスがあるかのように動作しfinallyます。

コンパイラ 考慮していることの 1 つは、finallyブロックは常にそれに続くコードの前に実行returnされ、finallyブロック内に がある場合、 の後のコードreturn はまったく実行されないということです。したがってreturnfinallyブロック内の a は、その後のコードを到達不能にします。

TL;DR:あるケースでは、Java コンパイラが認識できるように設計されているため、"TEST" ステートメントに到達できません。それ以外の場合は、Java コンパイラが認識できるように設計されていないため、"TEST" ステートメントに到達できません。

于 2016-07-15T14:11:15.513 に答える