4

なぜJavaはメソッド内でラベル付きのブレークを使用できるのですか?これの特別な目的や使用法はありますか?ループとスイッチ内でのみ使用できると思いました。

public void testMeth(int count){
   label:
   break label;
}

しかし、以下はコンパイラエラーを示します。

public void testMeth(int count){
    break; // This gives an Error : break cannot be used outside of a loop or a switch
}
4

7 に答える 7

2

これを使用して、ネストされたループからすぐに抜け出すことができます。

out: { 
         for( int row=0; row< max; row++ ) {
             for( int col=0; col< max; col++ )
                 if( row == limit) break out;
             j += 1;
         }
     }

ループの外側を使用breakすることはあまり意味がありませんが、どこにいますbreakingか?void関数から抜け出すadarshrには、returnをポイントとして使用できます。

于 2012-05-16T11:49:23.427 に答える
2

理由はわかりませんが、動作はJava言語仕様#14.15で指定されています。

ラベルなしで壊す

ラベルのないbreakステートメントは、制御を最も内側の囲んでいるスイッチに移そうとしますが、while、do、またはすぐに囲んでいるメソッドまたは初期化子のforステートメント。ブレークターゲットと呼ばれるこのステートメントは、すぐに正常に完了します。
すぐに囲むメソッド、コンストラクター、または初期化子のswitch、while、do、またはforステートメントにbreakステートメントが含まれていない場合、コンパイル時エラーが発生します。

ラベルで破る(強調鉱山)

ラベル識別子を持つbreakステートメントは、そのラベルと同じ識別子を持つ、それを囲むラベル付きステートメント(§14.7)に制御を移そうとします。ブレークターゲットと呼ばれるこのステートメントは、すぐに正常に完了します。この場合、ブレークターゲットはswitch、while、do、またはforステートメントである必要はありません

ラベル付きの区切りを使用すると、ブロック全体(ループの場合もあります)の後でコードをリダイレクトできます。これは、ネストされたループの場合に役立ちます。ただし、Cgotoステートメントとは異なります。

CやC++とは異なり、Javaプログラミング言語にはgotoステートメントがありません。識別子ステートメントのラベルは、ラベル付きステートメント内の任意の場所に表示されるbreak(§14.15)またはcontinue(§14.16)ステートメントで使用されます。

于 2012-05-16T11:54:20.207 に答える
0

ループのコンテキスト外でラベルが役立つ場合のさらに別の例を次に示します。

boolean cond1 = ...
if (cond1) {
    boolean cond1 = ...
    if (cond2) {
        boolean cond3 = ...
        if (cond3) {
            bar();
        } else {
            baz();
        }
    } else {
        baz();
    }
} else {
    baz();
}

...になる...

label: {
    boolean cond1 = ...
    if (cond1) {
        boolean cond1 = ...
        if (cond2) {
            boolean cond3 = ...
            if (cond3) {
                bar();
                break label;
            }
        }
    }
    baz();
}

不自然な例ですが、明らかに、少し読みやすくなっています。ラベルを使用する必要があると感じた場合は、ほとんどの場合、コードをリファクタリングすることをお勧めします。

于 2012-05-16T13:03:00.890 に答える
0

ここのように、ラベル付きのブレークを使用して、ネストされたループから抜け出すことができます。

于 2012-05-16T11:50:28.707 に答える
0

returnループの外で使用するためのステートメントがあるからです!

public void testMeth(int count){
    if(count < 0) {
        return;
    }

    // do something with count
}
于 2012-05-16T11:53:45.403 に答える
0

私は自分自身で1つのクレイジーな使用法を見つけました。

public void testMeth(int count){
    label: if (true) {
          System.out.println("Before break");
          if (count == 2) break label;
          System.out.println("After break");
    }
    System.out.println("After IF");
}

また

public void testMeth(int count){

    namedBlock: {
        System.out.println("Before break");
        if (count == 0) break namedBlock;
        System.out.println("After break");
    }

    System.out.println("After Block");
}

これは「休憩後」を無視します。

于 2012-05-16T12:25:03.813 に答える
0

ラベル付きのbreakステートメントの使用は強くお勧めしません。GOTOとほぼ同じくらい悪いです。1回の休憩。ループやスイッチなどを終了するのに問題はありません。しかし、私の経験では、このようなラベルの付いたブレークの必要性は、制御フローの設計が悪いことを示しています。

ほとんどの場合、適切に配置された例外の方が意味があります。しかし、ただ、「ジャンプ条件」がエラーと見なされる場合。メソッドを正しくラベル付けすると、エラーと見なされるかどうかに影響を与えることができます。

メソッドが「getDrink()」と呼ばれ、「milk」オブジェクトを返す場合は、問題ありません。ただし、メソッドが「getWater()」と呼ばれる場合、ミルクを返す代わりに例外をスローする必要があります...

したがって、代わりに:

public class TestBad {

public static void main(String[] args) {
    String[] guys = {"hans", "john"};

    myLabel: {
        for(String guy: guys) {
            String drink = getDrink(guy);

            if(drink.equals("milk")) {
                // Handle "milk"??
                break myLabel;
            }

            // Do something with "non-milk"
        }
    }

    // Success? Non Success??
}

private static String getDrink(String guy) {
    if(guy.equals("hans"))
        return "milk";
    else
        return "water";
}

}

次を使用する必要があります。

public class TestGood {

public static void main(String[] args) {
    String[] guys = {"hans", "john"};

    try {
        handleStuff(guys);
    } catch (Exception e) {
        // Handle Milk here!
    }
}

private static void handleStuff(String[] guys) throws Exception {
    for(String guy: guys) {

        String drink = getWater(guy);

        // Do something with "water"
    }
}

private static String getWater(String guy) throws Exception {
    if(guy.equals("hans"))
        // The method may NEVER return anything else than water, because of its name! So:
        throw new Exception("No Water there!");
    else
        return "water";
}

}

Fazit:ブロックをブロックまたは複数のループにネストする代わりに、メソッドをネストして適切な例外処理を使用する必要があります。これにより、読みやすさと再利用性が向上します。

于 2016-05-30T09:58:13.043 に答える