私はこの質問に気づいただけで、これに$.02を追加したいと思いました。
Javaの場合、これは実際にはオプションではありません。「到達不能コード」エラーは、JVM開発者が開発者を何かから保護したり、特に警戒したりすることを考えたという事実からではなく、JVM仕様の要件から発生します。
JavaコンパイラとJVMはどちらも、「スタックマップ」と呼ばれるものを使用します。これは、現在のメソッドに割り当てられた、スタック上のすべてのアイテムに関する明確な情報です。JVM命令が、あるタイプのアイテムを別のタイプに誤用しないように、スタックのすべてのスロットのタイプを知っている必要があります。これは、数値がポインタとして使用されるのを防ぐために最も重要です。Javaアセンブリを使用して、数値をプッシュ/保存しようとしますが、オブジェクト参照をポップ/ロードすることは可能です。ただし、JVMは、クラスの検証中、つまりスタックマップが作成され、整合性がテストされているときに、このコードを拒否します。
スタックマップを検証するには、VMはメソッドに存在するすべてのコードパスをウォークスルーし、どのコードパスが実行されるかに関係なく、すべての命令のスタックデータが以前のコードがプッシュしたものと一致することを確認する必要があります/スタックに保存されます。したがって、次の単純な場合:
Object a;
if (something) { a = new Object(); } else { a = new String(); }
System.out.println(a);
3行目で、JVMは'if'の両方のブランチがObjectと互換性のあるもの(ローカルvar#0)にのみ格納されていることを確認します(3行目以降のコードがローカルvar#0を処理する方法であるため) )。
コンパイラが到達不能コードに到達すると、その時点でスタックがどのような状態にあるかが完全にはわからないため、その状態を検証できません。ローカル変数も追跡できないため、その時点でコードを完全にコンパイルすることはできません。そのため、クラスファイルにこのあいまいさを残す代わりに、致命的なエラーが発生します。
もちろん、のような単純な条件if (1<2)
はそれをだますでしょうが、それは実際にはだまされていません-それはコードにつながる可能性のある分岐を与えており、少なくともコンパイラとVMの両方がそこからスタックアイテムをどのように使用できるかを決定できますの上。
PSこの場合、.NETが何をするのかわかりませんが、コンパイルも失敗すると思います。これは通常、マシンコードコンパイラ(C、C ++、Obj-Cなど)では問題になりません。