I was coding in JAVA and suddenly I wrote some code like this:
int x = 10;
boolean b = true;
l1: b = x > 1;
l2: while (b) {
// some code
break l2;
}
and to my surprise the code compiles and run properly. I'm doing nothing with my l1 label but why does it compile correctly with this statement?
I know that goto in java EXISTS but is not used (Java Language Keywords) but is there anyway that I can jump to it?
Any statement can be labeled, but they are only useful in conjunction with break or continue:
Unlike C and C++, the Java programming language has no goto statement; identifier statement labels are used with break (§14.15) or continue (§14.16) statements appearing anywhere within the labeled statement.
In other words, to be usable, the label needs to apply to a statement that contains a break or continue, which in turn can be a loop or, for break only, any block.
No, there is no way to jump back to l1 and continue execution. As you say, goto is an unused keyword. Labels are only useful for labeling loops to break/continue.
If you really want to "jump" to it, there are ways to do this through other programming techniques such as recursion.
i.e., if you wanted to jump back to l1 instead of just breaking l2...
public void myMethod() {
b = x > 1;
while (b) {
// some code
myMethod();
}
}
Be sure to add your return conditions though.
If you want to come out of many loops, you can use labeled continue statement. A work around for your code will be like this.
int x = 10;
boolean b = true;
l1:
for(int i=1;i>0;i--) { b = x > 1;
l2: while (b) {
// some code
//break l2;
i++;continue l1;
}
}
Related
I'm doing the simulation of Java OCA test. During my study with the book "OCA - Study Guide" (Sybex), at the second chapter there is the following (Table 2.5, page 91):
if - allows break statement: NO
if - allows continue statement: NO
But during the simulation of Java OCA test, did by Sybex (online book OCA), there is this question:
int x= 5;
while (x>=0) {
int y = 3;
while (y>0) {
if (x<2)
continue;
x--; y--;
System.out.println(x*y + " ");
}
}
My answer was: It doesn't compile
But the correct answer is:
8
3
0
2
What is the correct information?
What is right (book or simulation test)?
This is the table:
Thanks a lot!
I think what you need to understand is that in your code, the if statement is INSIDE a while loop (which is inside another while loop) and that's why it's OK to use continue in that case. An if statement outside of a loop isn't allowed to use continue. But inside of a for loop, while loop or do while loop, you CAN use continue inside an if statement.
So the code that you provided works and the output is:
8
3
0
2
But then I took your code and commented out the two while loops and now the code doesn't compile:
int x= 5;
// while (x>=0) {
int y = 3;
// while (y>0) {
if (x<2)
continue; //<-- COMPILE ERROR: continue cannot be used outside of a loop
x--; y--;
System.out.println(x*y + " ");
// }
// }
The output is:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
continue cannot be used outside of a loop
I wrote a very detailed Java looping tutorial that covers the continue statement, the break statement, and all the different types of loops in Java.
i think continue here is following the outer while loop not immediate if , since continue is allowed inside while loop it works.
public static void main(String[] args) {
int x= 5;
//while (x>=0) {
int y = 3;
//while (y>0) {
if (x<2)
continue;
x--; y--;
System.out.println(x*y + " ");
}
}
// }
// }
Error:(10, 21) java: continue outside of loop
Both book and test simulators are right. break and continue keywords are not allowed inside if. The continue you see inside if is perfectly valid because it appears within the context of outer while so that's fine. To wrap it all, when you start a while or for block, using break and continue everywhere inside this block is correct, even if it happens to be inside an if block.
normally break and continue are allowed in if statements but you should not use them that often because it is bad Coding stlye.
*unit = unit test framework
A Reason would be for example: If you try to test your software with unit (if you dont know unit not yet dont worry :D) it is much harder to understand what the code does than normally and also to test the code.
Good Luck and have fun hope i can help you
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 does not support goto, it is reserved as a keyword in case they wanted to add it to a later version
goto doesn't do anything in 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.
So I have a loop that is wrapped around a loop and an if statement. When running the program however, it gets out of the inner loop (as planned) and then it fails the if statement (also as planned), resorting to the else statement which is a simple print.
What I /wanted/ to happen was have it then (in the case the if fails), restart to the original inner loop--hence the outer loop. But instead, after it fails the if statement, it begins to loop "phrase2" over and over.
Here is the simplified code:
int x = 1;
int y = 1;
int i = 0;
while(i == 0)
{
while(<condition that is false>)
{
System.out.println("phrase1");
a = input.nextInt();
b = input.nextInt();
}
if(<condition that is false>)
{
i = 1;
}
else
{
System.out.println("phrase2");
}
}
Thanks for your help regardless!
EDIT:
For the sake of emphasis...
What happens:
Infinite loop spewing "phrase2".
What I wanted:
After the else is executed, I wanted to be brought into the inner loop again.
Whatever condition you're using in the inner loop, just make sure it's true.
else
{
System.out.println("phrase2");
// SET THIS TO TRUE: <condition that is false>
}
This way, the inner loop will trigger again.
Your control never enters the below if statement
if(<condition that is false>)
{
i = 1;
}
You might need to adjust your conditions so that it comes into the above if block. Introduce a System.out.println inside if statement to debug
It looks like you have some code that you probably want to run once, unless something went wrong, and then you want to go back and retry. The idiom I usually use for that looks like
boolean needToRetry;
do {
needToRetry = false;
// do whatever
if (somethingWentWrong) {
needToRetry = true;
// set this at any point where you find you will need to go back
}
} while (needToRetry);
The important thing is that you need to reset your flag (needToRetry) at the beginning of the loop, each time. (P.S. There are other ways to do this using break or continue, although I personally don't like using continue.)
Is breaking and continuing the only uses of labeled statements in Java?
When have you used Labeled Statements in your programs?
Sorry the code snippet has been deleted. I am splitting the question
JLS 14.7 Labeled statements
(edited for clarity)
Statements may have label prefixes (Identifier : Statement). The Identifier is declared to be the label of the immediately contained Statement.
Unlike C and C++, the Java programming language has no goto statement; identifier statement labels are used with break (§14.15) or continue (§14.16) statements appearing anywhere within the labeled statement.
So the JLS is clear that labels are used with break or continue, and no other grammatical element of the Java programming language uses it.
Strictly speaking, break and continue, labeled or not, are NEVER necessary. They can always be written out of the code. Used idiomatically, however, they can lead to more readable code.
Here's an illustrative example: given an int[], we want to :
print "One (1)" on 1
print "Two (2)" on 2
print "Zero " on 0
immediately stop processing on any other number
int[] arr = { 1, 2, 0, 1, -1, 0, 2 };
loop:
for (int num : arr) {
switch (num) {
case 1:
System.out.print("One ");
break;
case 2:
System.out.print("Two ");
break;
case 0:
System.out.print("Zero ");
continue loop;
default:
break loop;
}
System.out.print("(" + num + ") ");
}
// prints "One (1) Two (2) Zero One (1) "
Here we see that:
The different numbers are processed in a switch
Unlabeled break in the switch is used to avoid "fall-through" between cases
Labeled continue loop; is used to skip post-processing on case 0: (the label is not necessary here)
Labeled break loop; is used to terminate the loop on default: (the label is necessary here; otherwise it's a switch break)
So labeled break/continue can also be used outside of nested loops; it can be used when a switch is nested inside a loop. More generally, it's used when there are potentially multiple break/continue target, and you want to choose one that is not immediately enclosing the break/continue statement.
Here's another example:
morningRoutine: {
phase1: eatBreakfast();
if (grumpy) break morningRoutine;
phase2: kissWife();
phase3: hugChildren();
}
http://stackoverflow.com is the best website ever!
Here's another case of a labeled break being used not within an iterative statement, but rather within a simple block statement. One may argue that the labels lead to better readability; this point is subjective.
And no, the last line DOES NOT give compile time error. It's actually inspired by Java Puzzlers Puzzle 22: Dupe of URL. Unfortunately, the puzzle does not go into "proper" use of labeled statements in more depth.
Yes, break and continue are the only two uses for labeled statements in Java. (Java has no goto statement.)
You can use a label to break out of nested loops.
outer:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
System.out.println("Hello");
continue outer;
} // end of inner loop
System.out.println("outer"); // Never prints
}
System.out.println("Good-Bye");
When you continue back to the outer label, you're skipping the remainder of both the inner and the outer loop, including the print statement.
search:
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length; j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}
What is an alternative function for the goto keyword in Java?
Since Java does not have a goto.
You could use a labeled BREAK statement:
search:
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length; j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}
However, in properly designed code, you shouldn't need GOTO functionality.
There isn't any direct equivalent to the goto concept in Java. There are a few constructs that allow you to do some of the things you can do with a classic goto.
The break and continue statements allow you to jump out of a block in a loop or switch statement.
A labeled statement and break <label> allow you to jump out of an arbitrary compound statement to any level within a given method (or initializer block).
If you label a loop statement, you can continue <label> to continue with the next iteration of an outer loop from an inner loop.
Throwing and catching exceptions allows you to (effectively) jump out of many levels of a method call. (However, exceptions are relatively expensive and are considered to be a bad way to do "ordinary" control flow1.)
And of course, there is return.
None of these Java constructs allow you to branch backwards or to a point in the code at the same level of nesting as the current statement. They all jump out one or more nesting (scope) levels and they all (apart from continue) jump downwards. This restriction helps to avoid the goto "spaghetti code" syndrome inherent in old BASIC, FORTRAN and COBOL code2.
1- The most expensive part of exceptions is the actual creation of the exception object and its stacktrace. If you really, really need to use exception handling for "normal" flow control, you can either preallocate / reuse the exception object, or create a custom exception class that overrides the fillInStackTrace() method. The downside is that the exception's printStackTrace() methods won't give you useful information ... should you ever need to call them.
2 - The spaghetti code syndrome spawned the structured programming approach, where you limited in your use of the available language constructs. This could be applied to BASIC, Fortran and COBOL, but it required care and discipline. Getting rid of goto entirely was a pragmatically better solution. If you keep it in a language, there is always some clown who will abuse it.
Just for fun, here is a GOTO implementation in Java.
Example:
1 public class GotoDemo {
2 public static void main(String[] args) {
3 int i = 3;
4 System.out.println(i);
5 i = i - 1;
6 if (i >= 0) {
7 GotoFactory.getSharedInstance().getGoto().go(4);
8 }
9
10 try {
11 System.out.print("Hell");
12 if (Math.random() > 0) throw new Exception();
13 System.out.println("World!");
14 } catch (Exception e) {
15 System.out.print("o ");
16 GotoFactory.getSharedInstance().getGoto().go(13);
17 }
18 }
19 }
Running it:
$ java -cp bin:asm-3.1.jar GotoClassLoader GotoDemo
3
2
1
0
Hello World!
Do I need to add "don't use it!"?
While some commenters and downvoters argue that this isn't goto, the generated bytecode from the below Java statements really suggests that these statements really do express goto semantics.
Specifically, the do {...} while(true); loop in the second example is optimised by Java compilers in order not to evaluate the loop condition.
Jumping forward
label: {
// do stuff
if (check) break label;
// do more stuff
}
In bytecode:
2 iload_1 [check]
3 ifeq 6 // Jumping forward
6 ..
Jumping backward
label: do {
// do stuff
if (check) continue label;
// do more stuff
break label;
} while(true);
In bytecode:
2 iload_1 [check]
3 ifeq 9
6 goto 2 // Jumping backward
9 ..
If you really want something like goto statements, you could always try breaking to named blocks.
You have to be within the scope of the block to break to the label:
namedBlock: {
if (j==2) {
// this will take you to the label above
break namedBlock;
}
}
I won't lecture you on why you should avoid goto's - I'm assuming you already know the answer to that.
public class TestLabel {
enum Label{LABEL1, LABEL2, LABEL3, LABEL4}
/**
* #param args
*/
public static void main(String[] args) {
Label label = Label.LABEL1;
while(true) {
switch(label){
case LABEL1:
print(label);
case LABEL2:
print(label);
label = Label.LABEL4;
continue;
case LABEL3:
print(label);
label = Label.LABEL1;
break;
case LABEL4:
print(label);
label = Label.LABEL3;
continue;
}
break;
}
}
public final static void print(Label label){
System.out.println(label);
}
StephenC writes:
There are two constructs that allow you to do some of the things you
can do with a classic goto.
One more...
Matt Wolfe writes:
People always talk about never using a goto, but I think there is a
really good real world use case which is pretty well known and used..
That is, making sure to execute some code before a return from a
function.. Usually its releasing locks or what not, but in my case I'd
love to be able to jump to a break right before the return so I can do
required mandatory cleanup.
try {
// do stuff
return result; // or break, etc.
}
finally {
// clean up before actually returning, even though the order looks wrong.
}
http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html
The finally block always executes when the try block exits. This
ensures that the finally block is executed even if an unexpected
exception occurs. But finally is useful for more than just exception
handling — it allows the programmer to avoid having cleanup code
accidentally bypassed by a return, continue, or break. Putting cleanup
code in a finally block is always a good practice, even when no
exceptions are anticipated.
The silly interview question associated with finally is: If you return from a try{} block, but have a return in your finally{} too, which value is returned?
The easiest is:
int label = 0;
loop:while(true) {
switch(state) {
case 0:
// Some code
state = 5;
break;
case 2:
// Some code
state = 4;
break;
...
default:
break loop;
}
}
Try the code below. It works for me.
for (int iTaksa = 1; iTaksa <=8; iTaksa++) { // 'Count 8 Loop is 8 Taksa
strTaksaStringStar[iCountTaksa] = strTaksaStringCount[iTaksa];
LabelEndTaksa_Exit : {
if (iCountTaksa == 1) { //If count is 6 then next it's 2
iCountTaksa = 2;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 2) { //If count is 2 then next it's 3
iCountTaksa = 3;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 3) { //If count is 3 then next it's 4
iCountTaksa = 4;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 4) { //If count is 4 then next it's 7
iCountTaksa = 7;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 7) { //If count is 7 then next it's 5
iCountTaksa = 5;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 5) { //If count is 5 then next it's 8
iCountTaksa = 8;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 8) { //If count is 8 then next it's 6
iCountTaksa = 6;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 6) { //If count is 6 then loop 1 as 1 2 3 4 7 5 8 6 --> 1
iCountTaksa = 1;
break LabelEndTaksa_Exit;
}
} //LabelEndTaksa_Exit : {
} // "for (int iTaksa = 1; iTaksa <=8; iTaksa++) {"
In modern Java I would just use switch and String. I am surprised that I couldn't find this answer:
for (String label = "start";;) {
switch (label) {
case "start":
...
case "something":
...
case "whatever":
...
label = "something"; break; // <== those two commands equal goto
...
default:
return;
}
}
Use a labeled break as an alternative to goto.
Java doesn't have goto, because it makes the code unstructured and unclear to read. However, you can use break and continue as civilized form of goto without its problems.
Jumping forward using break -
ahead: {
System.out.println("Before break");
break ahead;
System.out.println("After Break"); // This won't execute
}
// After a line break ahead, the code flow starts from here, after the ahead block
System.out.println("After ahead");
Output:
Before Break
After ahead
Jumping backward using continue
before: {
System.out.println("Continue");
continue before;
}
This will result in an infinite loop as every time the line continue before is executed, the code flow will start again from before.