清空if语句

时间:2013-05-07 21:31:21

标签: java language-design

通过"清空if语句",我的意思是这样的(注意分号):

if (condition);

我在考虑应用程序时遇到了麻烦。使用while循环,您可以执行此操作:

while (callUntilReturnsFalse());

但是if-statement没有这样的申请。更重要的是,Java编译器在面对这样的语句时不会发出错误或警告。这可能导致大型和沉默问题,特别是在冗长而复杂的陈述中:

if ((functionA() && functionB(getFoo()) ||
    checkForComplexCondition(arg1, arg2, getBar(getFoo())));
{
    doStuff();
}

我的问题是:为什么Java允许这样做?而且,更重要的是,我可以启用一个选项,以便在发生这种情况时发出警告吗?

(关于C#,这个问题是asked before,它发出警告,但我希望找到一种方法来引发Java警告。)

10 个答案:

答案 0 :(得分:14)

为什么在Java中允许这样做?

请参阅Java Language Specification (14.6. The Empty Statement)

  

空语句什么都不做。

它只是被允许而且等同于(并将被翻译成):

if (condition) {  }

这意味着,如果条件为真,则不执行任何操作。

如果你正在使用eclipse,你可以看看这里,你可能会发现一些有用的东西(我不确定是否存在分号终止符的选项):

窗口首选项 Java 编译器错误/警告 < / p>

enter image description here


修改

正如@nullptr在他的回答中指出的那样,存在一个IDE警告,你需要在空语句上设置警告

答案 1 :(得分:13)

我不认为这与问题的意图真正相关,但我认为应该说明这与问题的实质相关。

的效果:

if(variable);

如果变量是volatile。它的作用是在当前线程和访问变量的任何其他线程之间使内存屏障受到尊重。

public volatile variable;
....
if(variable);

有关更详细的讨论,请参阅here

我无法想象在你的代码中加入这种语句会有什么真正的价值,但我觉得重要的是要注意在这种非常具体的情况下这种说法会产生真正的影响。

答案 2 :(得分:4)

我经常使用一个构造,“null语句”使得更清晰,更容易理解。这是一个例子:

for (int i=0;  i < argc;  i++)
{
   if (argv[i]=="left")
      hpos++;
   else if (argv[i]=="right")
      hpos--;
   else if (argv[i]=="up")
      ;
   else if (arv[i]=="down")
      ;
   else fprintf(stderr, "Unknown option \"%s\\n".", argv[i]);
}

在这种情况下,我仍然想检查某些选项的存在,而只执行某些的代码。在这种情况下,使用null语句,如上所述,使得代码的功能和结构对于必须出现并维护它的下一个人来说更具可读性和可理解性。

有一些方法可以重构此代码以不需要null语句。但我不相信它的意图会像代码片段那样清晰。

答案 3 :(得分:2)

对于if空语句的可能性,我没有看到太多危险。它背后的基本原理在于Java语言的语法,它允许空语句;

Block: 
    { BlockStatements }

BlockStatements: 
    { BlockStatement }

BlockStatement:
    LocalVariableDeclarationStatement
    ClassOrInterfaceDeclaration
    [Identifier :] Statement

LocalVariableDeclarationStatement:
    { VariableModifier }  Type VariableDeclarators ;

Statement:
    Block
    ;
    Identifier : Statement
    StatementExpression ;
    if ParExpression Statement [else Statement] 
    assert Expression [: Expression] ;
    switch ParExpression { SwitchBlockStatementGroups } 
    while ParExpression Statement
    do Statement while ParExpression ;
    for ( ForControl ) Statement
    break [Identifier] ;
    continue [Identifier] ;
    return [Expression] ;
    throw Expression ;
    synchronized ParExpression Block
    try Block (Catches | [Catches] Finally)
    try ResourceSpecification Block [Catches] [Finally]

请注意,几乎所有命令式语言都是如此。

我的意思是,如果你忘记任何实施,它可能是危险的,很难找到其他空洞的身体,当然没有什么我会失去睡眠。在漫长而复杂的陈述中,您可能会遇到问题,因为( )关闭了错误的表达式,甚至认为您的情况不对(特别是对于许多&&||)。

答案 4 :(得分:2)

我在Eclipse中发现了Empty statement

的警告

example

感谢Maroun Maroun让我走上正轨。

答案 5 :(得分:1)

我主要是一名C#开发人员,虽然我有一点Java背景。但我认为我的答案适用于两者。我怀疑它不是故意的特征,而是更多的新兴特征。语言的语法(大致)

if (*condition*)
    *statement*

不幸的是,以下两个都是有效的语句(我检查过,您可以根据需要删除多少C#,并且编译器不会抱怨):

;

{
}

因此,您突出显示的构造是允许的。

答案 6 :(得分:1)

条件可能是带副作用的函数调用。将其视为错误或警告是不正确的。

答案 7 :(得分:0)

声明

if  (eval) { //pseudo-code
}

有时数据在评估(eval)时实际发生了变化。例如,在

while (someIterator.next()) {
}

调用next()实际上会更改someIterator对象的状态。

当然,有一个典型的例子,通常是从拼写错误(并不推荐)

int x;  
if (x = getNumberOfWidgets() > 5) {
}

传统智慧建议不要采用这种方式进行编码,因为很难说出正在发生的事情。但是,这些陈述是合法的,因此这是允许这种“if”陈述的一个原因。

答案 8 :(得分:0)

我相信他们留下了它,因为它可以提高代码的可读性。即使案件没有采取任何措施,你仍然可以让人们知道案件很重要。

答案 9 :(得分:0)

大多数Java编译器根本不进行代码优化。他们在运行时将此工作委托给Java Runtime Environment。 JVM在执行代码之前验证代码,此验证(主要)包含三个检查:

  1. 分支在有效位置(与正确无关)。
  2. 数据始终初始化,引用始终是类型安全的
  3. 控制对私人数据的访问。
  4. 因此,您的if声明可能错误,但它仍然有效。与

    一样有效
     if (a==a)