jls 中的一些定义解释了这一点(第 14 章):
块是语句
如 here 所述,Block 是 StatementWithoutTrailingSubstatement,而 StatementNoShortIf 又是 Statement。因此,无论何时需要这些,我们都可以插入Block。
if 子句
虽然for 和while-loops 也是如此,但我将使用if-statements。这些规则几乎相同。 if-statements 的语法描述可以在here 找到。
IfThenStatement:
if ( Expression ) Statement
IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement
IfThenElseStatementNoShortIf:
if ( Expression ) StatementNoShortIf else StatementNoShortIf
所以我们可以在这里使用我们的块。
但为什么它与 ; ?
; 定义为EmptyStatement (link),它也是StatementNoShortIf。因此,在有条件的代码片段中,例如if-statement 和循环,如果需要StatementNoShortIf 或Statement,我们可以将Block 替换为EmptyStatement。
因此if(Expression)EmptyStatement 有效。
为什么不报错?
很简单:如果 java 发现无效的语法,它会报错。但是if(Expression)EmptyStatement 是完全有效的语法。相反,javac 如果使用正确的参数启动,则会发出警告。为此,full list of warnings that can be dis-/enabled 列出了警告名称empty。所以用-Xlint:all 或-Xlint:empty 编译会产生一个警告。
您的 IDE 也应该有一个选项来启用这种警告。
对于日食,请参阅@nullptr's answer。在 IntelliJ 中,您可以按 Ctrl + Shift + A,在搜索字段中输入 empty body 并启用警告(在图像中标记)
这到底是干什么用的?
老实说,从简约的角度来看,它并没有多大用处。通常有一种方法可以在没有“什么都不做”命令的情况下完成任务。个人喜好的问题,你是否更愿意使用
if( a() && b() );
或
if( a() ) b();
同样适用于使用EmptyStatement 的其他情况。关于这个主题要考虑的一个重要点是代码的可读性。在某些情况下,通过使用 no-op,代码变得更具可读性。另一方面,在某些情况下,使用EmptyStatement 会使代码变得非常难以理解——上面的例子将被计入后来的 IMO。