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は決して実行されないことを知っています。しかし、それでもコンパイル時エラーがスローされる理由がわかりません。 「ステートメントに到達できません」というコンパイルエラーが発生します。
それはコンパイラがコードのすべてのブランチ/行に対してコンパイルできるかどうかをチェックすることを意味しますか?
それはコンパイラがコードのすべてのブランチ/行に対してコンパイルできるかどうかをチェックすることを意味しますか?
これは、コンパイラがすべてのステートメントに到達できることを確認することを意味します。
から JLSのセクション14.21 :
到達できないためにステートメントを実行できない場合は、コンパイル時エラーです。
このセクションは、「到達可能」という言葉の正確な説明に専念しています。その考え方は、ステートメントを含むコンストラクター、メソッド、インスタンス初期化子、または静的初期化子の先頭からステートメント自体への実行パスがいくつか存在する必要があるということです。分析では、ステートメントの構造が考慮されます。
次に、到達可能性の定義方法について説明します。
特に、あなたのケースの関連ポイントは次のとおりです。
Sの前のステートメントが正常に完了できる場合に限り、スイッチブロックではない空でないブロック内の他のすべてのステートメントSに到達できます。
break
、continue
、return
、またはthrow
ステートメントは正常に完了できません。
したがって、「行1」ステートメントの前にはステートメント(break;
)これはできません正常に完了できないため、到達できません。
コンパイラーもその結論を出すことができ、間違いを犯していると想定します。はい、Javaコンパイラはかなりの量の「データフロー分析」を実行します。最も一般的な関連メッセージは、初期化されていない変数に関するメッセージです。2番目に頻繁に発生するのは、正確には、これは到達できないコードについてです。
それはコンパイラがコードのすべてのブランチ/行に対してコンパイルできるかどうかをチェックすることを意味しますか?
はいコンパイラはコード全体をコンパイルし、コードに従ってバイトコードを作成します。unreachable code
もdead code
を検出するのに十分なほどスマートです。 for-loop
の即時break
は、他のステートメントに到達できないようにします。
for(;;){
break;
... // unreachable statement
}
int i=1;
if(i==1)
...
else
... // dead code
到達できないコードは意味がなく、冗長です。プログラムに到達できないコードがある場合、それは誤りであり、修正する必要があります。したがって、コンパイラはエラーをスローします。
以下の同様の質問を参照できます
コンパイラーは、これら2つのステートメントが決して実行されないことを判別でき、コンパイルを拒否することで正しいコードを作成するのに役立ちます。実行されます。
コンパイラーは、特定のキーワードの後にさらにコードがあるかどうかをチェックします。同様のメッセージを表示する別のキーワードは、break
をreturn
で置き換える場合です。