Semicolon at end of 'if' statement

2018-12-31 04:21发布

Today, after half an hour of searching for a bug, I discovered that it is possible to put a semicolon after an if statement instead of code, like this:

if(a == b);
// Do stuff

Which basically means that the stuff will be done whether a equals b or not, and the if statement has no point whatsoever. Why doesn't Java give me an error? Is there any situation in which this would be useful?

16条回答
君临天下
2楼-- · 2018-12-31 04:33

I can't think of an occasion where it is useful. It can be useful for loops like

 while(do something);

or

 for(init; do something; something else);

If you use your code formatting in your IDE regularly these sort of bugs become obvious. Some IDEs highlight this as a probable bug as well.

查看更多
骚的不知所云
3楼-- · 2018-12-31 04:33

I'd agree with you there's no useful purpose to this for a human. I suspect it's there because it simplifies the language definition; it means that the thing that comes after an if is e same as the thing that comes after a while, for instance.

查看更多
梦醉为红颜
4楼-- · 2018-12-31 04:35

If you use an if statement, the first statement after the if will be executed if the condition is true. If you have a block after the if (with curly braces), it counts for that whole block. If there is no block it counts for only one statement. A single semicolon is an empty statement. You could also write the code from you example like this:

if(a==b) {
    ;
}
查看更多
旧人旧事旧时光
5楼-- · 2018-12-31 04:39

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:

    They can instantly highlight problems such as this one.

I would recommend to combine both solutions.

查看更多
孤独寂梦人
6楼-- · 2018-12-31 04:40

Why? It's because its easier for compiler writers. You don't have to make a special case to check for semicolons after if(cond) and has an added usage of allowing

if (cond && maybeFunc())
    ;// Code here I want to ignore

Even though it's actually a terrible idea to allow this. It's just easier to allow and then to add a case to check this.

查看更多
残风、尘缘若梦
7楼-- · 2018-12-31 04:41

A few definitions from the jls explain this (chapter 14):

Blocks are Statements

As stated here, a Block is a StatementWithoutTrailingSubstatement, which in turn is a StatementNoShortIf, which is a Statement. Thus where ever any of these is required, we can insert a Block.

The if-clause

Though this is as well the case for for and while-loops, I'll use if-statements. These rules are pretty much the same. The syntactical description of if-statements can be found here.

IfThenStatement:
    if ( Expression ) Statement

IfThenElseStatement:
    if ( Expression ) StatementNoShortIf else Statement

IfThenElseStatementNoShortIf:
    if ( Expression ) StatementNoShortIf else StatementNoShortIf

So we can use our block here.

But why does it work with ; ?

; is defined as the EmptyStatement (link), which is as well a StatementNoShortIf. So in conditional pieces of code, like if-statement and loops, we can replace a Block with a EmptyStatement, if a StatementNoShortIf or Statement is required.

Thus if(Expression)EmptyStatement works.

Why doesn't this give an error?

Pretty simple: java gives an error if it finds invalid syntax. But if(Expression)EmptyStatement is perfectly valid syntax. Instead javac gives a warning if launched with the proper parameters. The full list of warnings that can be dis-/enabled lists the warning-name empty for this purpose. So compilation with -Xlint:all or -Xlint:empty will generate a warning about this.

Your IDE should have an option to enable this kind of warning as well. For eclipse, see @nullptr's answer. In IntelliJ, you can press Ctrl + Shift + A, enter empty body into the search field and enable the warning (marked in the image)

IntelliJ enable empty-body warning

What is this even used for?

To be honest, there's not much use in it from a minimalistic point of view. There's usually a way to get things done without a "do nothing" command. It's rather a question of personal preferences, whether you rather use

if( a() && b() );

or

if( a() ) b();

and same would apply to other cases, in which the EmptyStatement is used. An important point to consider on this topic is readability of code. There are occasions, where code becomes more readable by using the no-op. On the other hand there are cases, where code becomes quite a lot harder to comprehend with using the EmptyStatement - the above example would count to the later IMO.

查看更多
登录 后发表回答