将break语句作为一种goto语句使用

break语句除了与switch语句和循环语句一起使用之外,也可以作为一种“文明”的goto语句单独使用。Java没有goto语句,因为该语句提供的是改变程序执行流程的非结构化的方法。大量使用goto语句的程序通常难以理解,难以维护。然而,在有些地方goto语句却是合理有用的。例如,goto语句在从嵌套很深的循环退出时就很有用。为处理这些情况,Java定义了break语句的一种扩展形式。通过使用这种形式的break语句,可以从一个或多个代码块中退出。这些代码块不需要是循环或switch语句的一部分。他们可以是任何代码块。不仅如此,还可以精确的指定执行流继续执行的位置,因为这种形式的语句在工作时有一个标记。如你所见,break语句只为你提供goto语句的优点,却不会带来goto语句产生的问题。
带有标记的break语句的基本形式如下所示:
break label;
这里,label用于标识代码块的标记名。当这种break语句执行时,控制权就会转移到代码块外。已标记的代码块必须包含break语句,但不必立刻结束代码块。这就意味着可以使用带标记的break语句从一系列嵌套代码块中退出。然而,不能使用break语句把控制权转移到另一个不包含break语句的代码块。
要命名一个代码块,只需要在他的前面加标记就可以。被标记的代码块可以是单独的代码块,也可以是以代码块作为目标的语句。label可以是任何后面跟有冒号的有效的java标识符。一旦对一个代码块进行了标记,就可以把这个标记作为break语句的目标。这样做会使执行流在已标记的结尾继续执行。
    public static void main(String[] args) throws java.io.IOException
    {
        int i;
        
        for(i=1;i<4;i++)
        {
            one:
            {
                two:
                {
                    three:
                    {
                        if(i == 1) break one;
                        if(i == 2) break two;
                        if(i == 3) break three;
                    }
            
                    System.out.println("after block three i="+i);
                }
                System.out.println("after block two i="+i);
            }
            System.out.println("after block one i="+i);
        }
    }
输出:
after block one i=1
after block two i=2
after block one i=2
after block three i=3
after block two i=3
after block one i=3
仔细研究程序,以便弄明白这个结果是如何产生的。当i为1时,第一个if语句成立,这使得控制权转移到标记one定义的代码块的结尾,输出“atfer block one”,当i为2时,第二个if成立,使得控制权转移到标记two定义的代码块的结尾,输出消息“after block two”和“after block one”,当i等于3时,控制将转移到标记three定义的代码块结尾,这时就会显示所有三条消息。
问:你说goto是非结构化的,而带有标记的break语句提供了一种更好的方式,但是使用break中断并跳转到许多行和嵌套层之外不也是一种非结构化的方法吗?
答:简言之,的确如此。但是在程序的执行流需要跳转的情况下,跳转到标记还可以保留一些结构化特性,而使用goto则不能。