33

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();
    }
}
StackFlowed
  • 6,664
  • 1
  • 29
  • 45
Ungeheuer
  • 1,393
  • 3
  • 17
  • 32
  • 1
    Welcome to Java. While `goto` is a keyword in java, it has no functionality and will result in a compile error (as you noted in your question). – DwB Oct 17 '14 at 17:51
  • 1
    Even if you find the perfect use case and it totally makes sense, find another way to do it. At best most of the people you work with will think less of you. It's not actually that bad, but you'll never get past the stigma. – Bill K Oct 17 '14 at 17:57
  • 2
    As for what you are trying to do with the label, by the way, break and continue can specify a label (much as you'd expect goto to) – Bill K Oct 17 '14 at 17:59
  • 1
    JSR for goto in java (look at the date posted): https://blogs.oracle.com/darcy/entry/upcoming_jep – Asaf Oct 17 '14 at 18:00
  • I haven't seen a need to use `goto` in modern programming languages even where they do allow it. (Older versions of COBOL and Pascal are a different story, though, because they didn't have all the control statements modern languages do, particularly `break`, and there were cases where trying to work around those deficiencies without using `goto` resulted in less readable code. But it's unlikely you'll need to use one of those languages.) – ajb Oct 17 '14 at 18:13
  • @wrongAnswer, I had the (Line 1) in there so those of you who read my code know what I mean by Line 10. It was merely a reference. – Ungeheuer Oct 18 '14 at 15:15
  • @BillK, why is there a stigma? From what I just learned, if `goto` actually worked, it would have the same function as `break`? or is there a difference between `break` and what `goto` would hypothetically do? – Ungeheuer Oct 18 '14 at 15:20
  • @espertus very funny comic strip. – Ungeheuer Oct 18 '14 at 15:25
  • upvote my question please guys. I need some nice reputation. – Ungeheuer Oct 18 '14 at 15:26
  • 2
    @JohnnyCoder The stigma goes back to the way programmers _used_ to use `goto`'s. In other words, not just to break out of a loop--but any place they felt like it, all over the place. Ever heard the term "spaghetti code"? If you drew lines showing where the `goto`'s started and ended, it would look like a plate of spaghetti. (P.S. I have been programming long enough to remember when spaghetti code was how I and everyone around me wrote programs. We didn't know any better, yet.) – ajb Oct 18 '14 at 20:39
  • @JohnnyCoder You may want to check out [this information](http://en.wikipedia.org/wiki/Goto#Criticism) for some of the history. – ajb Oct 18 '14 at 20:41
  • @ajb thank you very much. I have not heard of the term, but that would explain fully why our class's Microsoft liason told me that using `goto` was not a smart thing to do. – Ungeheuer Oct 18 '14 at 22:16
  • 7
    @JohnnyCoder A lot of beginning programmers don't understand that the goal of code in most situations is NOT to make the computer do something, it's to make it easy for the next guy to understand, repair, and maintain it as easily as possible. After a decade or two of programming--Being bitten by crappy code that is very difficult to understand and maintain--most programmers understand the importance of maintainability and soon forget that there is any other way to think. Jumping across vast areas of code makes maintenance very challenging. Break and continue can't just jump anywhere like goto – Bill K Oct 19 '14 at 05:37

8 Answers8

94

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.

Community
  • 1
  • 1
Tirath
  • 2,294
  • 18
  • 27
  • 4
    This was extremely helpful. I'm going to have to print out this answer and put it in my binder to study and use. +1. You deserve +100, but I cant do that. :) – Ungeheuer Oct 18 '14 at 15:18
  • 6
    It's a great answer, +1, but if you ever have the desire to do this you are doing it wrong, period--refactor instead, break out a few other well-named methods instead. If you use this construct then at best you avoid a needed refactor, leaving your code messy AND you obfuscate it with a structure that few programmers understand. More likely you will be thought of as a poor programmer by the rest of the team for being unable to make clearer code. The desire to do this should be considered a very bad code smell. – Bill K Nov 25 '14 at 17:02
  • 3
    @BillK Well, I would argue that with basic commenting you can do this clearly. As long as those on the team can comprehend this, it seems fine to me. That said, I am somewhat inexperienced with teams and probably have no idea what I am talking about. – Jax Sep 23 '16 at 13:45
14

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.

Aditya Singh
  • 2,343
  • 1
  • 23
  • 42
  • 3
    all right. thank you. I hope they add `goto` it is so convenient. – Ungeheuer Oct 18 '14 at 15:19
  • 2
    I hope they will never use it. After using the Java language (and earlier C/C++) for more than 10 years, I always found better way to design function/methods not to use that "bug creator" way. Just have a look to the [apple ssl implementation security breach](http://www.theguardian.com/technology/2014/feb/25/apples-ssl-iphone-vulnerability-how-did-it-happen-and-what-next). Ok, they also forgot another best practice: always use curly braces even it make the code more verbose... – рüффп Dec 17 '15 at 16:01
  • 2
    Been programming 30+ years. Started with C. `goto` was available to me from the start and has been avoided completely the entire time. Initially, other programmers shamed me away from using it. In time, I saw enough usages of `goto` to give me my own convictions and sense of aversion to it. But, I have seen a few (very few) uses (by other programmers, poor souls) where it was cleaner to use `goto` than to write the equivalent without it. Those uses probably got de-factored later on. – Les Sep 12 '17 at 19:45
  • in c# only place where goto is useful is to have switch fall through. java supports fall through without goto. so there is really no need for goto in java. – M.kazem Akhgary Dec 10 '18 at 18:44
  • `goto` is obviously one of the most powerful constructs available to any programming language, even more so than constructs that build off of it, like conditional branches. It would be great to see it added to the language to really make Java complete. – Kröw Apr 17 '21 at 17:05
10

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("Even number: " + i +
                                   ", continue from OUTER label");
                continue OUTER;
            }
          
            INNER:
            for(int j = 0; j<numbers.length; j++){
                System.out.println("Odd number: " + i +
                                   ", break  from INNER label");
                break INNER;
            }
        }      
    }
}

Read more

Bill K
  • 62,186
  • 18
  • 105
  • 157
5

Java does not support goto, it is reserved as a keyword in case they wanted to add it to a later version

  • 4
    They should add it. It makes life so much easier. – Ungeheuer Oct 18 '14 at 15:16
  • 1
    @Ungeheuer Counter Intuitively GOTO is considered harmful. [Argument of Dijkstra](https://www.cs.utexas.edu/users/EWD/transcriptions/EWD02xx/EWD215.html) – Tarun Maganti Mar 28 '17 at 09:52
  • Goto is useful for method differed/exit statement processing. Lots of returns within code is evil. To build tons of "if" statements just to get common exit block also makes life much more complex. So goto is very welcome. – Madars Vi Feb 25 '19 at 10:51
3

goto doesn't do anything in Java.

Sizik
  • 1,066
  • 5
  • 11
2

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.

1

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

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.

Tatarize
  • 10,238
  • 4
  • 58
  • 64