Why does a Java if statement fail when it ends in semicolon
This semicolon ends a statement (an empty one), so your code is translated by the compiler to something like this:
if(name != null && value != null)
{
//nothing here
}
{
System.out.println("Values not null");
}
In other words, if if
expression is true
, it executes empty block of code. Then no matter whether if
was true or not, the runtime proceeds and runs the block containing System.out
. Empty statement is still a statement, so the compiler accepts your code.
Another place where such a mistake can happen:
for(int i = 0; i < 10; ++i);
{
System.out.println("Y U always run once?");
}
or even worse (infinite loop):
boolean stop = false;
while(!stop);
{
//...
stop = true;
}
It took me hours to discover what the issue was
Good IDE should immediately warn you about such statement as it's probably never correct (like if(x = 7)
in some languages).
Semicolon at end of 'if' statement
Why does it happen?
Java Language Specification says that:
The Empty Statement
An empty statement does nothing.
EmptyStatement:
;Execution of an empty statement always completes normally
It essentially means that you want to execute empty statement if a==b
if(a == b);
What should you do:
There are two main solutions to this problem:
You can avoid problems with empty statement by using code formatter
and surrounding stuff insideif
with{
and}
. By doing this
Your empty statement will be much more readable.if(a == b){
;
}You can also check tools used for static code analysis such as:
- Findbugs
- Checkstyle
- Pmd
They can instantly highlight problems such as this one.
I would recommend to combine both solutions.
What happens when if statement is ended with a semi colon
The if
statement has nothing to do with the following block:
if (i == 10);
This is a valid statement as ;
denotes an empty statement: if (i == 10)
then do nothing.
{
System.out.println("It is here");
break;
}
This is a valid code block. It is syntactically correct although it does not help a lot in this case. This block will be executed in all cases and is not affected by the if
statement above.
Why is an extra semicolon not allowed after the return statement, when it is allowed for other statements?
Why multiple semicolon is not allowed after the return statement, when
it is allowed for all other statement?
Simply because when you have a statement like
System.out.println();;
This means you have two statements, one is System.out.println();
and other statement is after the first semi colon
, it is empty and that's allowed BUT you can't have any empty statement or any other statement after the return
statement because it will never execute, in other words, its unreachable statement and you can't have unreachable statements in your code.
Same thing happens in this code too
if(a == b)
System.out.println();;
else
System.out.println();
that's because, when you have an else
statement, statement just before it should be if
statement which is not the case in above code snippet because statement just before else
statement is an empty statement
which is not allowed.
If you have parenthesis after the if statement
like
if(a == b) {
System.out.println();;
}
else
System.out.println();
you will get no errors because now empty statement is inside an if block
and the statement just before else
is if statement
and not the empty statement
which was the case when you had no parenthesis after if statement
Why enhanced for loop does not fail when ends with semicolon?
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, printi
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);
Why does Java not show an error for double semicolon at the end of a statement?
Because a double semicolon is not treated as a double semicolon but as a semicolon plus an empty statement. And an empty statement, which does nothing, is not an error.
Misplaced semicolon in for loop
If you place semicolon after a for loop then it is technically correct syntax. Because it is considered as an empty statement - that means nothing to execute.
In your case -
for(i=0;i<n;i++);
An empty statement executed up to n
times. Or in other words the for-loop
simply runs n
times.
The curly braces {}
after the for loop executed only once. Now the code block inside the curly braces {}
considered as a floating block.
Why are semicolons not used after if/else statements?
- Semicolon is used to end ONE statement
{
and}
begin and close a group of statements
Basically, an if-else
must be followed by either a statement or a group of statements.
if-else
followed by a statement:
if (condition) statement;
if (condition); // followed by a statement (an empty statement)
if-else
followed by group of statements:
if (condition) {
statement;
statement;
}
if (condition) {
// followed by a group of statements of zero length
}
if-else
must end with a ;
if it is followed by a single statement. if-else
does not end with a ;
when followed by a group of statements because ;
is used to end a single statement, and is not used for ending a group of statements.
Compiler doesn't complain when I ended a line with two semicolons. Why?
It's an empty statement and is valid. As pointed out by jwodder, to be more precise the empty statement is the lack of statement between the two semicolon and could be represented by two consecutive semicolons or by semicolons separated by white space (that is including new lines).
IDE like Eclipse will warn you about this. If you check the picture below, I've inserted a double semicolon on line 236. The red lines were added by me to focus the attention, but Eclipse give many visual cues:
- a jagged yellow line under the semicolons.
- a light bulb with a warning sign on the left margin of line 236, by hovering on that line, it will popup a small message saying "Unnecessary semicolon".
- on the bar containing the directories and packages, the warning sign is shown again. It is shown for every package or source folder, which contains at least one warning.
- on the package explorer and on the navigator file icon the same light bulb icon will be shown (not in this screenshot).
Related Topics
Differencebetween Reader and Inputstream
What Is the Time Complexity Performance of Hashset.Contains() in Java
What Are the Date Formats Available in Simpledateformat Class
How to Ignore Pkix Path Building Failed: Sun.Security.Provider.Certpath.Suncertpathbuilderexception
Determining Current Call Stack (For Diagnostic Purposes)
Why String.Replaceall() in Java Requires 4 Slashes "\\\\" in Regex to Actually Replace "\"
How to Set an Environment Variable at Runtime from Java
Difference Between Webdriver.Get() and Webdriver.Navigate()
Byte Array to Short Array and Back Again in Java
String S = New String("Xyz"). How Many Objects Has Been Made After This Line of Code Execute
Changing Java Platform on Which Netbeans Runs
Checking If Unlimited Cryptography Is Available
Ordering of Elements in Java Hashset
Spring Web MVC - Validate Individual Request Params
How to Apply Multiple Predicates to a Java.Util.Stream