清空if语句
通过“空if语句”,我的意思是这样的(注意分号):
if (condition);
我很难想到这个应用程序。 使用while循环,您可以执行以下操作:
while (callUntilReturnsFalse());
但是if语句没有这样的申请。 更重要的是,Java编译器在面对这样的语句时不会发出错误或警告。 这可能会导致大而沉默的问题,特别是有一个漫长而复杂的陈述:
if ((functionA() && functionB(getFoo()) || checkForComplexCondition(arg1, arg2, getBar(getFoo()))); { doStuff(); }
我的问题是:为什么Java允许这样做? 而且,更重要的是,我可以启用一个选项,以便在发生这种情况时发出警告吗?
( 之前就C# 提出了这个问题,它确实发出警告,但我希望找到一种方法来引发Java警告。)
为什么在Java中允许这样做?
请参阅Java语言规范(14.6。空语句) :
空语句什么都不做。
它只是被允许而且相当于(并将被翻译为):
if (condition) { }
这意味着,如果条件为真,则什么也不做。
如果你正在使用eclipse,你可以看看这里,你可能会发现一些有用的东西(我不确定是否存在这样的分号终止符选项):
窗口 → 首选项 → Java → 编译器 → 错误/警告
编辑
正如@nullptr在他的回答中指出的那样,存在一个IDE警告,你需要在Empty语句中设置警告 。
我不认为这与问题的意图真正相关,但我认为应该说明它与问题的实质相关。
有一个效果:
if(variable);
如果变量是volatile
。 它的作用是在当前线程和访问变量的任何其他线程之间使内存屏障受到尊重。
public volatile variable; .... if(variable);
请参阅此处以获取更详细的讨论。
我无法想象在你的代码中加入这种语句有什么真正的价值,但我觉得重要的是要注意在这种非常具体的情况下这个语句会产生真正的影响。
我经常使用一种构造,“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语句,如上所述,使得代码的function和结构对于必须出现并维护它的下一个人来说更具可读性和可理解性。
当然有一些方法可以重构此代码以不需要null语句。 但我不相信它的意图会像代码片段那样清晰。
我没有看到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]
请注意,几乎所有命令式语言都适用 。
我的意思是,如果你忘记任何实施,它可能是危险的,很难找到其他空的身体,当然没有什么我会失去睡眠。 在漫长而复杂的陈述中,你可能会遇到问题,因为( )
关闭了错误的表达式,甚至认为你的情况不对(特别是对于许多&&
和||
)。
我在Eclipse中发现了一个警告为Empty statement
:
感谢Maroun Maroun让我走上正轨。
我主要是一名C#开发人员,虽然我有一点Java背景。 但我认为我的答案适用于两者。 我怀疑它不是故意的特征,而是更多的新兴特征。 语言的语法(粗略地)
if (*condition*) *statement*
不幸的是,以下都是有效的语句(我检查过,您可以根据需要删除尽可能多的C#,并且编译器不会抱怨):
; { }
因此,允许您突出显示的构造。
条件可以是具有副作用的函数调用。 将其视为错误或警告是不正确的。
在声明中
if (eval) { //pseudo-code }
有时,数据在评估(eval)时实际发生了变化。 例如,在
while (someIterator.next()) { }
调用next()实际上会更改someIterator对象的状态。
当然还有一个典型的例子,通常是从错字中发生的(并且不推荐)
int x; if (x = getNumberOfWidgets() > 5) { }
传统智慧建议不要采用这种方式进行编码,因为很难说出正在发生的事情。 但是,这些陈述是合法的,因此这是允许这种“if”陈述的一个原因。
我相信他们留下了它,因为它可以提高代码的可读性。 即使案件没有采取任何措施,你仍然可以让人们知道案件很重要。
大多数Java编译器根本不进行代码优化。 他们在运行时将此工作委托给Java Runtime Environment。 JVM在执行代码之前validation代码, 但此validation(主要)包括三个检查:
- 分支处于有效位置(与正确位置不同)。
- 始终初始化数据,并且引用始终是类型安全的
- 访问私人数据受到控制。
所以,你的if
语句可能是错误的 ,但它仍然有效。 同样有效
if (a==a)