分号在'if'语句结束时

Eri*_*ten 65 java if-statement

今天,经过半小时的搜索bug,我发现可以在if语句后面加一个分号而不是代码,如下所示:

if(a == b);
// Do stuff
Run Code Online (Sandbox Code Playgroud)

这基本上意味着无论a是否等于b都会完成,if语句没有任何意义.为什么Java没有给我一个错误?有什么情况可以使用吗?

Mar*_*zak 85

为什么会这样?

Java语言规范说:

空陈述

空语句什么都不做.

EmptyStatement:
    ;
Run Code Online (Sandbox Code Playgroud)

执行空语句总是正常完成

它本质上意味着如果a == b,你想要执行空语句

if(a == b);
Run Code Online (Sandbox Code Playgroud)

你该怎么办:

这个问题有两个主要的解决方案:

  1. 您可以通过使用代码格式化及周边内的东西避免空语句的问题if{}.通过这样做你的空语句将更具可读性.

    if(a == b){
      ;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您还可以检查用于静态代码分析的工具,例如:

    他们可以立即突出这个问题.

我建议结合两种解决方案.

  • 你不能通过使用大括号来避免这种情况,因为在关闭paren之后和开放大括号之前的意外分号是一个语法上有效的程序......可能不是你想要的.但我同意,物质代码可能有助于避免此问题. (8认同)
  • 即使是最简单的解决方案,使用代码格式化程序,也可以解决这个问题.意图在if中的声明将出现在与if相同的缩进处. (6认同)

Tim*_*ora 28

有什么情况可以使用吗?

有用?如"使您的代码更清晰,更清晰,更快速,更易于维护"?一点也不.这很可能是糟糕的,令人困惑的代码.

但它不一定是良性的.由于引起副作用的方法,这样的语句可以执行动作和/或改变状态,并且可选地由于操作符的短路来评估那些方法.

if( a() && b() );
Run Code Online (Sandbox Code Playgroud)

在这里,a()或者b()可以做某事,b()只有在a()真实的情况下才会执行.

至于为什么,我认为答案很简单,偏离定义的预期行为(例如语句while(reader.read());)比编写错误代码的开发人员的选择更糟糕.

编写错误的代码总是可能的.而且重申一下,几乎在任何情况下这都是糟糕的代码.

  • @gefei - 就我而言,它是*可怕的*风格. (9认同)
  • 不,它只是让未来的读者感到困惑,这是否是一个错字.为什么不只是超级清晰,只是更加冗长?`if(!a())b();` (2认同)

gef*_*fei 19

一个可能的用例:

if (a==b);
else {
  // Do something
}
Run Code Online (Sandbox Code Playgroud)

不好,但可能.

不过,我确实认为Java规范应该禁止空if.

  • 仍然`if(a!= b)`似乎更具可读性 (13认同)
  • 像这样的代码实际上可以通过计算所有情况来防止逻辑错误."如果真的什么也不做,否则......"可以更具可读性,因为你不会被否定错误和"缺失案例"弄糊涂.现在大多数编译器都知道这种结构,无论如何都要为你提速以提高速度.例如,Mercury语言强制执行此操作! (3认同)
  • @tudor我想说,即使对于这种用例,也最好做if(a == b){//不做任何动作} else {doSomething(); }`,因为更明显的是,无操作是故意的而不是错字。 (2认同)

nul*_*ptr 11

如果你正在使用Eclipse,你可以让它警告你那些语句:

Java的>反编译>错误/警告


And*_*nek 8

如果使用if语句,if则条件为真时将执行第一个语句.如果你有一个块if(带花括号)后,它会计入整个块.如果没有阻止,则只计算一个语句.单个分号是一个空语句.您也可以编写您的示例代码,如下所示:

if(a==b) {
    ;
}
Run Code Online (Sandbox Code Playgroud)


Edw*_*uck 7

从存在更多语法糖以区分表达式和陈述的日子开始,这是一个古老的遗留物.

基本上,逗号用作列表项分隔符,因此分号用作"语句列表"分隔符.缺点是处理列表中的空项和块中的空语句.

在项列表中,Java使用显式关键字null,但"空语句"只是一个空行.允许存在空行是继承自C的传统.

为什么这样?特别是if当你知道没有语句被执行时的语句:因为一些if语句有副作用:

 int c;
 if ((c = in.read()) != -1);
Run Code Online (Sandbox Code Playgroud)

是的,它不是最好的例子,但基本上它表示从流中读取一个字节并且什么都不做.在一些极端情况下可能有用,但即使这个例子不是最好的,它也说明了意图.我们想要感受表达式的副作用,而不会意外地执行任何语句.


Pet*_*rey 5

我想不出它有用的场合.它可以用于循环

 while(do something);
Run Code Online (Sandbox Code Playgroud)

要么

 for(init; do something; something else);
Run Code Online (Sandbox Code Playgroud)

如果您经常在IDE中使用代码格式,那么这些错误就会变得很明显.一些IDE也强调这是一个可能的错误.