14

ラベルはループでのみ使用する必要があるといつも思っていましたが、そうではないようです。そのようなコードを与える:

public class LabelTest {
    public static void main(String[] args) {
        label1: System.out.println("");
        label2: LabelTest t = new LabelTest();  
    }                                               
}

「label1」というラベルの付いた行をコンパイルすると、コンパイルされますが、「label2」のコードでエラーが発生します。なぜですか?そして、なぜ「ループ」ではないステートメントにラベルを付けたいのでしょうか?

4

6 に答える 6

18

変数宣言にラベルを適用できないため、エラーが発生します。これは、言語の文法が定義されている方法です (ラベルは a の前にのみ使用できStatement、 aLocalVariableDeclarationStatementは a ではありませんStatement)。その理由は、おそらく、変数のスコープに関する混乱を招く可能性があるためです。これは機能します:

    label1: System.out.println("");
    label2: { LabelTest t = new LabelTest(); }
于 2011-02-20T15:40:36.370 に答える
7

Michael Borgwardt の回答に追加すると、便宜上次のようなことができます (先日、Java rt.jar ソース コードを読んでいるときにこれを発見しました)。

BlockSegment:
if (conditionIsTrue) {
    doSomeProcessing ();
    if (resultOfProcessingIsFalse()) break BlockSegment;
    otherwiseDoSomeMoreProcessing();
    // These lines get skipped if the break statement
    // above gets executed
}
// This is where you resume execution after the break
anotherStatement();

さて、これは論理的に次と同等です。

if (conditionIsTrue) {
    doSomeProcessing ();
    if (!resultOfProcessingIsFalse()) {
        otherwiseDoSomeMoreProcessing();
        // More code here that gets executed
    }
}
anotherStatement();

ただし、余分なブレース (およびブレースに付属するインデント) の一部をスキップできます。おそらく、見た目がすっきりしていて (私の意見ではそうです)、このスタイルのコーディングが適切で混乱が少ない場所がいくつかあります。

ifしたがって、ループだけでなく、ステートメントを超えてラベルを使用することもできます。たとえば、これは有効な Java 構文です (次のようなことを行う理由を思いつくかもしれません)。

statementOne();
statementTwo();
BlockLabel: {
    statementThree();
    boolean result = statementFour();
    if (!result) break BlockLabel;
    statementFive();
    statementSix();
}
statementSeven();

ここでbreakが実行されると、実行はラベルで示されるブロックの最後までスキップされ、スキップされstatementFive()ますstatementSix()

このスタイル (ifステートメントなし) の有用性は、スキップしなければならないブロック内にブロックがある場合により明白になります。 一般に、ループを十分に賢く使用すれば、すべてを達成できます。ただし、ループのないラベルを使用すると、コードが読みやすくなる場合がいくつかあります。たとえば、パラメータを順番にチェックする必要がある場合は、これを行うか、例外をスローします。最終的には、コードの清潔さと個人的なスタイルの問題になります。

于 2013-11-05T21:30:06.470 に答える
1

コンパイルされません。良い質問!私はあなたのコードスニペットで少し遊んだところです。コンパイラは、ラベルの後にメソッド呼び出しまたは演算子を期待しているようです。この時点で割り当ては許可されません。

for、while、do 以外の演算子の前にラベルが禁止されていないのは、おそらく仕様の Java コンパイラのバグ (?!) だと思います。とにかく、それほど重要ではありません。気になりません(個人的に)。

于 2011-02-20T15:36:18.723 に答える
1

Java 構文は C 構文に基づいています。

C では、(ループだけでなく) どこにでもラベルを付けて、 を使用gotoしてその行に実行をジャンプできます。現在、は Java で実装されていませんが、またはgotoと組み合わせて使用​​できるようにラベルが残されています。breakcontinue

とにかく、これはラベルの標準的な使用法ではないため、それほど重要ではありません。continueまたはでラベルを使用するbreakことは十分に悪いことです (ほとんどの場合)。勝手に使ってもダメです。

于 2011-02-20T15:40:03.890 に答える
-2

JLSのLable参照

于 2011-02-20T15:37:31.283 に答える