如何正确使用goto语句

时间:2014-10-17 17:47:43

标签: java loops goto

我正在上高中AP计算机科学课。

我决定向我们的一个实验室发送goto声明只是为了玩,但我收到了这个错误。

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
    Syntax error on token "goto", assert expected
    restart cannot be resolved to a variable
at Chapter_3.Lab03_Chapter3.Factorial.main(Factorial.java:28)

我在Stackoverflow上找了一个goto问题,找出如何正确地做到这一点,而且我完全按照其中一个答案进行了演示。我真的不明白为什么编译器需要一个assert语句(至少这是我认为它想要的),我也不知道如何使用assert。它似乎希望goto restart;的重启部分是变量,但重启只是一个标签,它将程序拉回到第10行,以便用户可以输入有效的int。如果它想重新启动变量,我该怎么做?

import java.util.*;

public class Factorial 
{
    public static void main(String[] args) 
    {
        int x = 1;
        int factValue = 1;
        Scanner userInput = new Scanner(System.in);
        restart:
        System.out.println("Please enter a nonzero, nonnegative value to be factorialized.");
        int factInput = userInput.nextInt();

        while(factInput<=0)
        {
            System.out.println("Enter a nonzero, nonnegative value to be factorialized.");
            factInput = userInput.nextInt();
        }

        if(x<1)//This is another way of doing what the above while loop does, I just wanted to have some fun.
        {
            System.out.println("The number you entered is not valid. Please try again.");
            goto restart;
        }
        while(x<=factInput)
        {
            factValue*=x;
            x++;
        }
        System.out.println(factInput+"! = "+factValue);
        userInput.close();
    }
}

8 个答案:

答案 0 :(得分:67)

正如所有答案goto已经指出的那样 - Java中的保留字并未在该语言中使用。

restart:被称为标识符,后跟冒号。

如果您希望实现similar行为,您需要注意以下几点:

outer:                  // Should be placed exactly before the loop
loopingConstructOne  {  // We can have statements before the outer but not inbetween the label and the loop          
    inner:
    loopingConstructTwo {
        continue;       // This goes to the top of loopingConstructTwo and continue.
        break;          // This breaks out of loopingConstructTwo.
        continue outer; // This goes to the outer label and reenters loopingConstructOne.
        break outer;    // This breaks out of the loopingConstructOne.
        continue inner; // This will behave similar to continue.
        break inner;    // This will behave similar to break.
    }
}

我不确定我是否应该像现在这样说similar

答案 1 :(得分:12)

Java keyword list指定goto关键字,但标记为“未使用”。

这可能是为了将它添加到更高版本的Java中。

如果goto不在列表中,并且稍后将其添加到语言中,则使用单词goto作为标识符(变量名,方法名等)的现有代码将会中断。但是因为goto是一个关键字,这样的代码甚至不能在当前编译,并且它仍然可以在以后实际执行某些操作,而不会破坏现有代码。

答案 2 :(得分:10)

如果你继续查看,他们会接受“标签”。试验一下。 Goto本身不起作用。

public class BreakContinueWithLabel {

    public static void main(String args[]) {

        int[] numbers= new int[]{100,18,21,30};

        //Outer loop checks if number is multiple of 2
        OUTER:  //outer label
        for(int i = 0; i<numbers.length; i++){
            if(i % 2 == 0){
                System.out.println("Odd number: " + i +
                                   ", continue from OUTER label");
                continue OUTER;
            }

            INNER:
            for(int j = 0; j<numbers.length; j++){
                System.out.println("Even number: " + i +
                                   ", break  from INNER label");
                break INNER;
            }
        }      
    }
}

Read more

答案 3 :(得分:4)

Java不支持goto,如果要将其添加到更高版本,则会将其保留为关键字

答案 4 :(得分:3)

goto在Java中没有做任何事情。

答案 5 :(得分:2)

Java也不使用行号,这是GOTO函数的必需品。与C / C ++不同,Java没有goto语句,但java支持label。标签在Java中有用的唯一位置就在嵌套循环语句之前。我们可以使用break指定标签名称以打破特定的外部循环。

答案 6 :(得分:0)

没有&#39;转到&#39;在Java世界中。主要原因是开发人员意识到具有goto的复杂代码会导致代码变得非常可悲,并且几乎不可能增强或维护代码。

然而,这段代码可以稍微修改一下,使用continue和break的概念,我们可以使代码工作。

    import java.util.*;

public class Factorial 
{
    public static void main(String[] args) 
    {
        int x = 1;
        int factValue = 1;
        Scanner userInput = new Scanner(System.in);
        restart: while(true){
        System.out.println("Please enter a nonzero, nonnegative value to be factorialized.");
        int factInput = userInput.nextInt();

        while(factInput<=0)
        {
            System.out.println("Enter a nonzero, nonnegative value to be factorialized.");
            factInput = userInput.nextInt();
        }

        if(x<1)//This is another way of doing what the above while loop does, I just wanted to have some fun.
        {
            System.out.println("The number you entered is not valid. Please try again.");
            continue restart;
        }
        while(x<=factInput)
        {
            factValue*=x;
            x++;
        }
        System.out.println(factInput+"! = "+factValue);
        userInput.close();
        break restart;
}
    }
}

答案 7 :(得分:0)

goto是该语言中未使用的保留字。因此没有goto。但是,如果您要使用荒诞派剧院,则可以从标签的语言功能中选择一种。但是,不是标记有时会有用的for循环,而是标记代码块。您可以在该代码块中调用标签上的break,将您吐到基本上是goto的代码块的末尾,这只会在代码中向前跳转。

    System.out.println("1");
    System.out.println("2");
    System.out.println("3");
    my_goto:
    {
        System.out.println("4");
        System.out.println("5");
        if (true) break my_goto;
        System.out.println("6");
    } //goto end location.
    System.out.println("7");
    System.out.println("8");

这将打印1、2、3、4、5、7、8。随着中断,代码块跳到了代码块之后。您可以移动my_goto: {if (true) break my_goto;} //goto end location.语句。重要的是,中断必须在标记的代码块内。

这比真正的goto还要丑。绝对不要这样做。

但是,有时使用标签和break很有用,并且知道如果您标记代码块而不是在中断时循环,则实际上很有用,您可以跳转。因此,如果您从循环内破坏代码块,不仅会中止循环,而且还会在循环结束和代码块之间跳过代码。