「空のifステートメント」とは、次のような意味です(セミコロンに注意してください)。
if (condition);
私はこのためのアプリケーションを考えるのに苦労しています。 whileループを使用すると、次のことができます。
while (callUntilReturnsFalse());
しかし、if文にはそのようなアプリケーションはありません。さらに、Javaコンパイラーは、このようなステートメントに直面したときにエラーや警告を発行しません。これにより、大きなsilent問題、特に長く複雑なステートメントに関する問題:
if ((functionA() && functionB(getFoo()) ||
checkForComplexCondition(arg1, arg2, getBar(getFoo())));
{
doStuff();
}
私の質問は、なぜこれがJavaで許可されているのかということです。さらに重要なことは、これが発生したときに警告を出すオプションを有効にできますか?
(この質問は 以前に尋ねた 警告を発行するC#に関してでしたが、Javaで警告を引き起こす方法を見つけたいと思っていました。)
なぜこれがJavaで許可されているのですか?
Java言語仕様(14.6。空のステートメント) を参照してください:
空のステートメントは何もしません。
それは単に許可されており、同等です(そして翻訳されます):
if (condition) { }
つまり、条件が真の場合、何もしません。
Eclipseを使用している場合は、こちらを参照してください。何か便利なものが見つかるかもしれません(セミコロンターミネータのようなオプションが存在するかどうかはわかりません)。
Window→Preferences→Java →コンパイラ→エラー/警告
@nullptrが彼の答えで指摘したように、IDEこれに対する警告が存在します。あなたはwarningを設定する必要があります空のステートメント。
私はこれが質問の意図に真に関連するとは思わないが、質問の本質に関連しているのでそれを述べるべきだと思う。
そこにはisの効果があります:
if(variable);
変数がvolatile
の場合。その効果は、現在のスレッドと変数にアクセスする他のスレッドとの間でメモリバリアが尊重されるようにすることです。
public volatile variable;
....
if(variable);
より詳細な議論については here をご覧ください。
この種のステートメントをコードに入れることの本当の価値は想像できませんが、この非常に特殊な状況では、このステートメントに実際の効果があることに注意することが重要だと感じました。
私がかなり頻繁に使用する構成要素が1つあります。これは、「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ステートメントを必要としないようにこのコードを再構築する方法は確かにあります。しかし、その意図がコードスニペットのように明確になるとは思わない。
EclipseでEmpty statement
としてこれに関する警告を見つけました:
私を正しい方向に導いてくれたMaroun Marounに感謝します。
空のステートメントを持つ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]
これはほとんどすべての命令型言語に当てはまることに注意してください。
実装を忘れた場合、他のすべての空のボディとして見つけるのは危険で困難になる可能性がありますが、確かに私は睡眠を失うことはありません。長く複雑な文では、( )
間違った表現のペアを閉じたり、条件を間違っていると考えるために(特に多くの&&
および||
)。
条件は、副作用を伴う関数呼び出しである可能性があります。エラーまたは警告として扱うのは正しくありません。
私は主にC#開発者ですが、少しのJavaバックグラウンドがあります。しかし、私の答えは両方に当てはまると思います。言語の文法が(大体)行く
if (*condition*)
*statement*
残念ながら、以下は両方とも有効なステートメントです(チェックしましたが、好きなだけC#にドロップでき、コンパイラーは文句を言いません):
;
{
}
したがって、強調表示した構造は許可されます。
コードを読みやすくするために残しておいたと思います。ケースに対して何もすべきでない場合でも、そのケースが重要であることを人々に知らせたい場合があります。
ほとんどのJavaコンパイラーはコードの最適化をまったく行いません。ランタイム中にこの作業をJava Runtime Environment。JVMは実行前にコードを検証し、 butこの検証は、(主に)3つのチェックで構成されます。
したがって、if
ステートメントはwrongかもしれませんが、それでも有効です。として有効
if (a==a)
声明で
if (eval) { //pseudo-code
}
(eval)の評価で実際にデータが変更される場合があります。たとえば、
while (someIterator.next()) {
}
Next()を呼び出すと、実際にsomeIteratorオブジェクトの状態が変更されます。
そしてもちろん、通常タイプミスから生じる典型的な例があります(推奨されません)
int x;
if (x = getNumberOfWidgets() > 5) {
}
何が起こっているのかわかりにくいため、従来の知恵ではこの方法でコーディングすることはお勧めしません。ただし、ステートメントは合法であるため、そのような「if」ステートメントが許可される理由の1つです。