I'm studying for a Java certification and on one of the mock exams I saw a very odd implementation of For loop. The exercise showed the following syntax :
for (Days d: Days.values());
At the beginning, I thought that it was a syntax error, since I always knew that the syntax for the "For loop" requires curly braces or, if there is only one instruction to iterate we can skip the curly braces and set our statement aligned just after the loop.
-- Since I haven't seen before a For loop ending with semicolon ";".--
Then I tried to find some documentation about it, but unfortunately I could not find any explanation why is a legal code declaration. Only references to the following syntax:
The syntax of enhanced for loop is:
for(declaration : expression)
{
//Statements
}
The odd thing is that after all of this, I tested my code and surprisingly it compiled and ran properly. Then, based on some tests that I did (playing with the code), I discovered that it seems that the ";" works like a For loop empty but with curly braces, so, any instruction after it, it is executed only one time. (As if the code where out of the loop). But I'm not sure if this is the right interpretation of the semicolon on the enhanced for loops.
Please see the complete example:
package com.TestDays;
public class TestDays {
public enum Days { MON, TUE, WED};
public static void main(String[] args) {
int x = 0;
*for (Days d: Days.values());*
Days[] d2 = Days.values();
System.out.println(d2[2]);
}
}
Does anyone knows why this syntax is allowed?
Thank you.
https://docs.oracle.com/javase/specs/jls/se7/html/jls-18.html
A for loop is defined as:
for ( ForControl ) Statement
; is a valid statement in Java, as is a block of statements. Not something you see often with this form of loop, but you can do things like:
int i = 2;
for(; i < 100; i*=2);
// i is now the smallest power of two greater than 100
Please note that in the documentation only mention the following syntax:
The syntax of enhanced for loop is:
for(declaration : expression)
{
//Statements
}
The "documentation" quoted your question comes from a page on TutorialsPoint (as seen by me on 2016-05-22). I'm not going to link to it, but assuming they have not corrected it (yet), you should be able to find it using a Google phrase search.
This is NOT the official documentation. The only official documentation for Java is the documentation written by Oracle (and previously Sun Microsystems) employees and published by these organizations.
TutorialsPoint has no standing. In this case, they have simply gotten the Java syntax wrong.
According to the Java 8 JLS, the real Java syntax for the enhanced for loop is1
EnhancedForStatement:
for ( {VariableModifier} UnannType VariableDeclaratorId : Expression )
Statement
EnhancedForStatementNoShortIf:
for ( {VariableModifier} UnannType VariableDeclaratorId : Expression )
StatementNoShortIf
where Statement and StatementNoShortIf include the empty statement; i.e. a bare semi-colon.
1 - The grammar rules are quoted from the Java 8 grammar. The "no short ifs" variant is about disambiguating nested if statements, and is not relevant here. In the Java 7 JLS, there are two versions of the grammar in the spec, one with the variants and one without them.
The documentation that you read is not the official documentation, since the authors would have written:
The enhanced for statement has the form for (declaration : expression) statement
This is because the braces are not needed.
A single semicolon forms a so-called _ empty statement_, and that makes your code snippet syntactically valid.
There are 3 main different ways a for-loop or enhanced for-loop can be created in Java:
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
for (int i = 0; i < 5; i++) System.out.println(i);
for (int i = 0; i < 5; i++);
These 3 loops are equivalent to:
For every time i is less than 5, do whatever is between {} and increment its value by one.
For every time i is less than 5, print i and increment its value by one.
For every time i is less than 5, increment its value by one.
Its not a matter of, "why doesn't it fail", its more, "what the for-loop is being told to do".
Specifically, WHY it doesn't fail, is the way the for-loop syntax is laid out. This was explained very well in Stephen C's answer:
According to the Java 8 JLS, the real Java syntax for the enhanced for loop is
EnhancedForStatement:
for ( {VariableModifier} UnannType VariableDeclaratorId : Expression )
Statement
EnhancedForStatementNoShortIf:
for ( {VariableModifier} UnannType VariableDeclaratorId : Expression )
StatementNoShortIf
As you can see, Statement refers to any valid statement, which includes the usage of ;, as ; is a valid "Statement". Because this is allowed, there is no reason why it should fail in any case.
Infact, another way to interpret for (int i = 0; i < 5; i++); would be:
"For every time i is less than 5, run statements, and increment its value by one."
Same rules can be applied to:
for (Integer i : ints) {
System.out.println(i);
}
for (Integer i : ints) System.out.println(i);
for (Integer i : ints);
Related
I have a question about for loops in java. I understand how for loops work an using the format :
for(initialize variable : condition : counter){}
My problem is in one of my lectures it says:
for(String s : str){.....}
How come this doesn't need a counter?
What is str?
This is an enhanced for loop, or a "for each" loop. It iterates over all the elements of str, which is probably a Collection of Strings in your example, or an Array of Strings.
Read this for more details.
For example, instead of writing this:
for (int i = 0; i < myArray.length; i++) {
System.out.println(myArray[i]);
}
you can write its equivalent:
for (int myValue : myArray) {
System.out.println(myValue);
}
First of all replace : with ; in the first for loop like this(you have used wrong syntax)
for(initialize variable ; condition ; counter){}
and the second one is the enhanced for loop,
for(String s : str){.....}
quite handy in case of the collections,It does not require any counter because it runs till it reaches the last element in the collection provided to it(In this case str is that collection)
See this to learn more about it What is the syntax of enhanced for loop in Java?
It is an enhanced for loop that iterates through every element in the Collection. It doesn't stop until it is has hit the last element or encounters a break;.
Your definitive source for this sort of questions is the Java Language Specification. In this particular case:
http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14
A more friendly source may be found in the official Java Tutorials, in this case:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html
I have a code like this
public class Test
{
public static void main(String[] args)
{
continue s;
System.out.println("I am not supposed to print this");
s:
System.out.println("I am suppose to print this");
}
}
I get the error
java: undefined label: s
What is wrong ?
Basically, there is no practical way to do that in Java. You appear to be trying to do the equivalent of a "goto", and that is not supported in Java. The break label and continue label statements can only branch to an enclosing labelled statement.
Now according to the Java formal grammar you could write this:
s: {
continue s;
System.out.println("I am not supposed to print this");
}
System.out.println("I am suppose to print this");
but that still won't compile for two reasons:
The continue is only allowed to branch to a label on a loop statement. (A break doesn't have that restriction ... but ...)
The continue (or a break) makes the next statement unreachable.
See also: Alternative to a goto statement in Java
But there is one rather tricky way to get your code to "work":
static final boolean flag = true; // class attribute ...
...
s: {
if (flag) break s;
System.out.println("I am not supposed to print this");
}
System.out.println("I am suppose to print this");
The "test" there will be evaluated by the compiler so that the break is effectively unconditional. But the JLS says that the first println will be treated as reachable, so that you won't get an unreachable code error.
I guess this might be useful if you are generating this source code. Apart from that, it is (IMO) just a curiosity. It is simpler to do this with a regular if / else statement ... or by deleting the first "print" entirely.
Jumping like this is not possible in Java, only way to jump is from loops, while and do.
What is the "continue" keyword and how does it work in Java?
Read #Heinzi answer
2.2.6 No More Goto Statements
Java has no goto statement. Studies illustrated that goto is (mis)used more often than not simply "because it's there". Eliminating goto led to a simplification of the language--there are no rules about the effects of a goto into the middle of a for statement, for example. Studies on approximately 100,000 lines of C code determined that roughly 90 percent of the goto statements were used purely to obtain the effect of breaking out of nested loops. As mentioned above, multi-level break and continue remove most of the need for goto statements.
The Java Language Environment, James Gosling
and Henry McGilton, 1996
There is no "goto" in java. And "continue" does a little bit other function. You can use "continue" for example in loops like:
class ContinueDemo {
public static void main(String[] args) {
String searchMe = "peter piper picked a " + "peck of pickled peppers";
int max = searchMe.length();
int numPs = 0;
for (int i = 0; i < max; i++) {
// interested only in p's
if (searchMe.charAt(i) != 'p')
continue;
// process p's
numPs++;
}
System.out.println("Found " + numPs + " p's in the string.");
}
}
In the example above, if for example searchMe.charAt(5) != 'p' then the loop will continue from the beginning of loop from i=6, and numPs++; will not be processed.
You can read more about this here:
Branching Statements
continue is a keyword in Java used to skip iterations of a loop.
If you are trying to find an equivalent to GOTO, you should reconsidering how you are trying to solve your problem, GOTO is never a valid option, ever.
As far as I know, there is no goto in Java (there is a keyword, but it has no meaning)
Theoretically, Java have Jump statements return and break.
The return statement jumps out of a method, with or without returning values to the calling statement.
The break statement jumps out of loops.
As mentioned in the earlier answers, goto is not available in Java, and is not considered to be a good programming practice in procedural or object oriented programming. It existed back in the days of sequential programming.
Eclipse lets me write some code like this, and doesn't show any errors:
for (SomeClass c : listOfSomeClass) if (c.someBoolean) {
// actions to take if someBoolean is true
}
Will this behave as expected, or is this not valid Java?
It's valid. The if will get repeated as many times as there are elements of listOfSomeClass. But that doesn't mean that writing Java like this is a good idea. Please don't ever do this.
You could even write something like
for (SomeClass c : listOfSomeClass) if (c.someBoolean) System.out.println(c);
if you were feeling particularly perverse.
However, when you write code, it's important to write code that another programmer can easily read, understand, and modify if necessary. Once a software system is in production, you can be fairly sure that changes will be required in it at some point in the future. What you can't be sure of is exactly what those changes will be.
So a good programmer, a professional programmer, writes his/her code in a way that makes it as easy as possible to change; and that means as easy as possible to understand. Now we professional programmers get used to seeing code laid out in certain ways. Curly braces used with for and with if, whether they're actually required or not. Consistent indentation. Intuitive use of variable names, and so on. Anything slightly unusual slows us down.
I don't want to be scratching my head, trying to work out how code works. I don't want to have to THINK about which lines are part of the for loop, or the if branch. I want code that tells me what it does, the first time I cast my eyes upon it. So, if you are EVER on the same team as me - or on the same team as any programmer who vaguely resembles me - then for the love of all that is good in this world, write this loop exactly like this.
for (SomeClass element : listOfSomeClass) {
if (element.shouldBePrinted()) {
System.out.println(element);
}
}
It works fine, but the formatting it likely to be confusing. Even you are not sure of what it will do. I suggest you use the standard formatter in eclipse to produce something like
for (SomeClass c : listOfSomeClass)
if (c.someBoolean) {
// actions to take if someBoolean is true
}
This is valid Java code and this is the same as:
for (SomeClass c : listOfSomeClass) {
if (c.someBoolean) {
// actions to take if someBoolean is true
}
}
Actually Java allows you to write a one-line statement after the for loop condition. Example:
for (int i = 0; i < 10; i++)
System.out.println(i);
Note that this style is usually discouraged since it can lead to misunderstanding of what the code does.
Informally, the for construct has this grammar:
for (...) statement
Normally, statement will take the form {set of instructions each separated by;} but, of course, it's possible to omit the braces for a single statement.
Since if (...){ } is a statement, your code is valid.
But it is obscure though: at the very least adhere to an established convention and start the if on the next line with an extra level of indentation. I always use braces when writing a for loop but that's a personal choice and plenty of well-respected coders don't.
yes it can be done,the if loop
if (c.someBoolean) {
// actions to take if someBoolean is true
}
will be executed multiple times
What ever is there immediately after the for loop will be executed.
for example
for(int i=0;i<10;i++)
System.out.println("welcome");
is same as
for(int i=0;i<10;i++)
{
System.out.println("welcome");
}
So it will print welcome 10 times.
But this example
f
or(int i=0;i<10;i++)
System.out.println("welcome");
System.out.println("outside");
will print welcome 10 times and outside one time.
The above code is similar to
for(int i=0;i<10;i++)
{
System.out.println("welcome");
}
System.out.println("outside");
if you want multiple line execution in loop then you write it like this
for (SomeClass c : listOfSomeClass)
{
//multiple lines to be executed
System.out.println("print this awesome line");
}
now if you want only a sinle code line to execute accoring to the loop then you write it like this
for (SomeClass c : listOfSomeClass)
System.out.println("print this awesome line");
now this line can be any valid line of code
thus if condition is also allowed
if(awesomeCondition)
{
System.out.println("print this awesome line in side legendary if condition");
}
thus your final code is
for (SomeClass c : listOfSomeClass)
if(awesomeCondition)
{
System.out.println("print this awesome line in side legendary if condition");
}
which is equally compatible to
for (SomeClass c : listOfSomeClass)
{
if(awesomeCondition)
{
System.out.println("print this awesome line in side legendary if condition");
}// end of IF block
}// end of for loop
It is valid. If you do not use curly braces "{", then only the first command is executed. For example, if you had another command after the "if" block, it would not be a part of your "for" loop.
Example:
for (int i=0; i<3; i++)
System.out.println(i);
System.out.println("Hello");
will print:
0
1
2
Hello
and not:
0
Hello
1
Hello
2
Hello
The second output would be printed if you had the following code:
for (int i=0; i<3; i++) {
System.out.println(i);
System.out.println("Hello");
}
However, it is recommended to use the block statement.
If you look at the Java Language Specification of for you'll see (for the enhanced for):
for ( FormalParameter : Expression ) Statement
And the definition of Statement is:
Statement:
StatementWithoutTrailingSubstatement
...
IfThenStatement
...
StatementWithoutTrailingSubstatement:
Block
...
(I have left out some of the definitions)
In other words the statement in your question is equivalent to for ( FormalParameter : Expression ) Statement where Statement: IfThenStatement.
Now in general it is advisable to use a Block instead, or at least indent for better readability. Your statement is equivalent to:
for (SomeClass c : listOfSomeClass)
if (c.someBoolean) {
// actions to take if someBoolean is true
}
Or better yet:
for (SomeClass c : listOfSomeClass) {
if (c.someBoolean) {
// actions to take if someBoolean is true
}
}
Basically I'm quite new to Java and just been given some code which reads:
if (n > 1)
l--;
m = l;
Although I'm wondering whether this would be equivalent to either one of these, and if so which and why?
#1
if (n > 1) {
l--;
m = l;
}
OR
#2
if (n > 1) {
l--;
}
m = l;
It's equivalent to the second one. The if statement executes the next statement if its expression evaluates to true. It doesn't matter to the compiler if the next statement is a single statement (as it is in your original code sample) or a block (as it is in your second revision).
It's the same as the second block of code.
When you don't see braces following a "grouping" statement (the if statement, in your example), it means that only the next line falls within the scope of that grouping statement.
Going beyond what the question asks, languages such as Java, C/C++, and C# use braces to declare blocks of code, whereas languages such as Python use whitespace. You can think of line of code is a block by itself. Blocks can be incrementally built by combining more blocks. This is done by grouping blocks; in Java, this is done through curly braces. When the if statement is evaluated (or a for loop, or a while loop, etc), the next outermost block falls under that statement.
the 2nd option.
If there's no { }, only the following statement is part of the If case
Obviously #2, because a if statement only takes the first expression after it into account. That is why it is always important to use brackets around your statements, both for clarity and fewer bugs. There is nothing more frustrating than spending hours wondering why code doesn't work because you forgot to add a bracket somewhere
Everywhere else I write a statement in Java I need to end it with a semi-colon. However, that doesn't apply to the i++ of a for loop.
How comes?
Because it's special syntax with clear and agreed-upon semantic meaning interpretable by the compiler, because the designers of C/C++/Java/etc. arbitarily decided it should be so.
EDIT:
Some commenters have pointed out that the decision isn't really arbitary, since designers did it to maintain consistency with expression vs. statement syntax. I'm glad they pointed that out, because I didn't know that was the case. In my defense, they very clearly could have made the syntax require a semicolon in that position; the decision not to, while not entirely arbitrarily, represented a choice which could have been different. Ahem.
Because the ')' rather well terminates the update statement so it would be redundant?
Both in C and C++ it's like that, and Java copied much of the syntax of those languages, for making things easier for programmers coming from them.
Also, it really isn't necessary to end the statement with a ";", since the right parenthesis ")" demarcates where the statement ends.
I would spend some time learning the differences between an expression and a statement; as described here.
The parts of a for loop are expressions, not statements. Expressions are not terminated by semicolons. i++ is an expression. Likewise, you don't put a semicolon after the i++ here:
System.out.println(i++;);
// ^ wrong
That wouldn't make any sense. The same logic applies to if, and while loops.
If you think about it, really two of the three terms in a for loop aren't really statements. Take the canonical for loop
for(int ix = 0; ix < MAX; ix++){ /* do something */ }
that's really shorthand for
int ix = 0;
while(ix < MAX){ /* do something */ ; ix++; }
Notice that there's no semicolon for ix < MAX either. In the for loop, the semicolons are simply there to separate the terms somehow -- only by co-incidence (and a lack of extra symbols) is it the same as a statement terminator.