简体   繁体   中英

How to use goto statement correctly

I am taking my high school AP Computer Science class.

I decided to throw a goto statement into a one of our labs just to play around, but I got this error.

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)

I went to a goto question on Stackoverflow to find out how to do it properly, and I did exactly as was demonstrated in one of the answers. I really don't understand why the compiler wants an assert statement (at least that's what I assume it wants), nor do I have any idea how to use assert . It seems to want the restart part of goto restart; to be a variable, but restart is just a label that pulls the program back up to line 10 so that the user can enter a valid int . If it wants restart to be a variable, how do I do that?

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

As already pointed out by all the answers goto - a reserved word in Java and is not used in the language.

restart: is called an identifier followed by a colon.

Here are a few things you need to take care of if you wish to achieve similar behavior -

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.
    }
}

I'm not sure of whether should I say similar as I already have.

The Java keyword list specifies the goto keyword, but it is marked as "not used".

This was probably done in case it were to be added to a later version of Java.

If goto weren't on the list, and it were added to the language later on, existing code that used the word goto as an identifier (variable name, method name, etcetera) would break. But because goto is a keyword, such code will not even compile in the present, and it remains possible to make it actually do something later on, without breaking existing code.

If you look up continue and break they accept a "Label". Experiment with that. Goto itself won't work.

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

Java不支持goto ,它被保留为关键字,以防他们想要将其添加到更高版本

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

Java also does not use line numbers, which is a necessity for a GOTO function. Unlike C/C++, Java does not have goto statement, but java supports label. The only place where a label is useful in Java is right before nested loop statements. We can specify label name with break to break out a specific outer loop.

There is not 'goto' in the Java world. The main reason was developers realized that complex codes which had goto would lead to making the code really pathetic and it would be almost impossible to enhance or maintain the code.

However this code could be modified a little and using the concept of continue and break we could make the code work.

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

goto is an unused reserved word in the language. So there is no goto . But, if you want absurdist theater you could coax one out of a language feature of labeling. But, rather than label a for loop which is sometimes useful you label a code block. You can, within that code block, call break on the label, spitting you to the end of the code block which is basically a goto, that only jumps forward in code.

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

This will print 1, 2, 3, 4, 5, 7, 8. As the breaking the code block jumped to just after the code block. You can move the my_goto: { and if (true) break my_goto; and } //goto end location. statements. The important thing is just the break must be within the labeled code block.

This is even uglier than a real goto. Never actually do this.

But, it is sometimes useful to use labels and break and it is actually useful to know that if you label the code block and not the loop when you break you jump forward. So if you break the code block from within the loop, you not only abort the loop but you jump over the code between the end of the loop and the codeblock.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM