Why Do Java If Statement Fail When It Ends in Semicolon

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:

  1. You can avoid problems with empty statement by using code formatter
    and surrounding stuff inside if with { and }. By doing this
    Your empty statement will be much more readable.

    if(a == b){
    ;
    }
  2. You can also check tools used for static code analysis such as:

    Sample Image

    • 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:

  1. For every time i is less than 5, do whatever is between {} and increment its value by one.
  2. For every time i is less than 5, print i and increment its value by one.
  3. 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).

Sample Image



Related Topics



Leave a reply



Submit