12

我在开发应用程序时犯了一个编码错误,这是对空引用的测试。我花了几个小时才发现问题所在,但我不明白为什么代码会这样。

String name = null;
String value = null;

if(name != null && value != null);
{
    System.out.println("Values not null");
}

if 语句以 , 结尾;,那是我的错误,Values not null即使很明显两个值都为空,它也被打印出来了。谁能解释为什么?

4

9 回答 9

14

这个分号结束一个语句(一个空的),所以你的代码被编译器翻译成这样的东西:

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).

于 2012-10-07T19:44:08.223 回答
5

; terminates the statement.

if(name != null && value != null);

is equivalent to:

if(name != null && value != null)
{
}

And the following code is simply a block of code.

于 2012-10-07T19:44:45.487 回答
2
if(name != null && value != null);
{
    System.out.println("Values not null");
}

相当于:

if(name != null && value != null){}

{
    System.out.println("Values not null");
}
于 2012-10-07T19:43:53.210 回答
2
if(name != null && value != null);

Here your if statement got finished due to semi-colon...

So, it is just like an empty if block: -

if(name != null && value != null) {}

So your next code becomes an Initializer block: -

{
    System.out.println("Values not null");
}

Since it is an initializer block.. It will be executed always no matter what your if condition evaluated to..

于 2012-10-07T19:44:08.363 回答
1

It's the standard grammar rules. Semicolons terminate statements, but statements may be empty, so these lines:

if (...);
{
}

are equivalent to:

if (...) /* do nothing */ ;

{
    ...
}

The following { ... } statement just looks like any other code block, and will always be executed, because the if statement is done with by then.

于 2012-10-07T19:44:24.380 回答
1

Your code is equivalent to:

if(name != null && value != null) {
   // empty code block
}

System.out.println("Values not null");
于 2012-10-07T19:44:38.670 回答
1

The semi-colon ends the statement, and thus detaches the if from the following block.

Note that blocks can be arbitrary.

{
System.out.println("This is some code");
}

if(true); This is valid, and it does nothing. The language allowing this is pretty stupid, although IDEs should catch these issue with warnings and the like.

于 2012-10-07T19:45:16.877 回答
0

One bare ; is a whole empty statement. After the if there has to be exactly one statement that will be executed when if is true. The one statement that is executed in your case is the empty statement. You can combine more statements to one with {statement; statement;...}

于 2012-10-07T19:46:34.360 回答
0

Understand that conditional statements needn't always follow with opening and closing braces. Most languages will allow you to simply emit the braces if you only want to execute a single statement when the terms of the condition are met.

Meaning that the following is completely valid, for instance:

if (var1 == true && var2 == true) var3 = 'both true';
{
    //block here, this is always executed regardless of the statements outcome
}

Essentially, your code does exactly this. Except your single statement is determined to be ; (yes, this is considered a statement).

What you wrote is the same as:

if(name != null && value != null) {
    // do nothing
}

System.out.println("Values not null");
于 2012-10-07T19:47:52.257 回答