web-dev-qa-db-ja.com

到達できないステートメントコンパイルエラーJava

class For1
{
  public static void main(String args[])
  {
    int a = 0;
    for(;;)
    {
      break;
      System.out.println(a); //Line 1
      ++a;//Line 2
    }
  }
}

Line 1/Line 2は決して実行されないことを知っています。しかし、それでもコンパイル時エラーがスローされる理由がわかりません。 「ステートメントに到達できません」というコンパイルエラーが発生します。

それはコンパイラがコードのすべてのブランチ/行に対してコンパイルできるかどうかをチェックすることを意味しますか?

8
UnderDog

それはコンパイラがコードのすべてのブランチ/行に対してコンパイルできるかどうかをチェックすることを意味しますか?

これは、コンパイラがすべてのステートメントに到達できることを確認することを意味します。

から JLSのセクション14.21

到達できないためにステートメントを実行できない場合は、コンパイル時エラーです。

このセクションは、「到達可能」という言葉の正確な説明に専念しています。その考え方は、ステートメントを含むコンストラクター、メソッド、インスタンス初期化子、または静的初期化子の先頭からステートメント自体への実行パスがいくつか存在する必要があるということです。分析では、ステートメントの構造が考慮されます。

次に、到達可能性の定義方法について説明します。

特に、あなたのケースの関連ポイントは次のとおりです。

Sの前のステートメントが正常に完了できる場合に限り、スイッチブロックではない空でないブロック内の他のすべてのステートメントSに到達できます。

breakcontinuereturn、またはthrowステートメントは正常に完了できません。

したがって、「行1」ステートメントの前にはステートメント(break;)これはできません正常に完了できないため、到達できません。

13
Jon Skeet

コンパイラーもその結論を出すことができ、間違いを犯していると想定します。はい、Javaコンパイラはかなりの量の「データフロー分析」を実行します。最も一般的な関連メッセージは、初期化されていない変数に関するメッセージです。2番目に頻繁に発生するのは、正確には、これは到達できないコードについてです。

6
Mario Rossi

それはコンパイラがコードのすべてのブランチ/行に対してコンパイルできるかどうかをチェックすることを意味しますか?

はいコンパイラはコード全体をコンパイルし、コードに従ってバイトコードを作成します。unreachable codedead codeを検出するのに十分なほどスマートです。 for-loopの即時breakは、他のステートメントに到達できないようにします。

for(;;){
   break;
   ... // unreachable statement
}


int i=1;
if(i==1)
  ...
else
  ... // dead code

到達できないコードは意味がなく、冗長です。プログラムに到達できないコードがある場合、それは誤りであり、修正する必要があります。したがって、コンパイラはエラーをスローします。

以下の同様の質問を参照できます

到達不能コード:エラーまたは警告? および なぜJavaに「到達不能ステートメント」コンパイラエラーがあるのですか?

2
Aniket Thakur

コンパイラーは、これら2つのステートメントが決して実行されないことを判別でき、コンパイルを拒否することで正しいコードを作成するのに役立ちます。実行されます。

1
JB Nizet

コンパイラーは、特定のキーワードの後に​​さらにコードがあるかどうかをチェックします。同様のメッセージを表示する別のキーワードは、breakreturnで置き換える場合です。

0
npinti