在java方法中标记了破解

时间:2012-05-16 11:47:10

标签: java loops

为什么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
}

7 个答案:

答案 0 :(得分:2)

您可以使用此to break out of nested loops immediately

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函数,您可以使用return adarshr指出。

答案 1 :(得分:2)

我不知道原因,但行为是在Java Language Specification #14.15

中指定的

打破没有标签

  

没有标签的break语句尝试将控制转移到最里面的封闭开关,while,do或for语句用于立即封闭的方法或初始化器;这个语句叫做中断目标,然后立即正常完成   如果在立即封闭的方法,构造函数或初始化程序中没有switch,while,do或for语句包含break语句,则会发生编译时错误。

打破标签(强调我的)

  

带有标签Identifier的break语句尝试将控制转移到与其标签具有相同标识符的封闭标签语句(第14.7节);此语句称为中断目标,然后立即正常完成。 在这种情况下,中断目标不一定是开关,while,do或for statement

使用标签断开使您可以在整个块(可以是循环)之后重定向代码,这在嵌套循环的情况下很有用。 It is however different from the C goto statement

  

与C和C ++不同,Java编程语言没有goto语句;标识符语句标签与出现在标记语句中任何位置的break(§14.15)或continue(§14.16)语句一起使用。

答案 2 :(得分:0)

您可以使用带标签的符号来摆脱嵌套循环like here

答案 3 :(得分:0)

因为在循环之外有return语句可供使用!

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

    // do something with count
}

答案 4 :(得分:0)

我发现自己疯狂使用了一次。

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");
}

OR

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");
}

这忽略了“休息后”。

答案 5 :(得分: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();
}

显然,一个人为的例子,但更具可读性。我的建议是,如果你觉得需要使用标签,那么你应该重新编写代码。

答案 6 :(得分:0)

我强烈建议使用标记的break语句。它几乎和GOTO一样糟糕。一次休息;是否/必须结束一个循环或开关等。但根据我的经验:需要这样一个标签中断是一个糟糕的控制流设计的指标。

在大多数情况下,放置良好的异常会更有意义。但是,如果&#34; Jump-Condition&#34;可以看作是一个错误。如果你正确地标记你的方法,你可以影响,可以看作是什么错误。

如果您的方法被调用&#34; getDrink()&#34;它会返回一个&#34;牛奶&#34;对象,没关系。但是如果你的方法被调用&#34; getWater()&#34;,它应该抛出异常而不是返回牛奶......

所以而不是:

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:不应将Blocks嵌套到Blocks或多个循环中,而是应该嵌套方法并使用适当的异常处理。这增强了可读性和可重用性。