提问人:Erik Bergsten 提问时间:1/2/2013 最后编辑:double-beepErik Bergsten 更新时间:4/18/2019 访问量:52748
“if”语句末尾的分号
Semicolon at end of 'if' statement
问:
今天,在搜索了半个小时的 bug 之后,我发现可以在 if 语句后面加上一个分号而不是代码,如下所示:
if(a == b);
// Do stuff
这基本上意味着无论是否相等,这些事情都会完成,而这种说法没有任何意义。为什么 Java 不给我错误?在什么情况下这样做会有用吗?a
b
if
答:
为什么会这样?
空语句
空语句不执行任何操作。
EmptyStatement: ;
空语句的执行始终正常完成
它本质上意味着你要执行空语句,如果 a==b
if(a == b);
你应该怎么做:
这个问题有两种主要的解决方案:
通过使用代码格式化程序,可以避免空语句的问题 和周围的东西里面有和.通过这样做 你的空洞陈述将更具可读性。
if
{
}
if(a == b){ ; }
您还可以检查用于静态代码分析的工具,例如:
他们可以立即突出显示诸如此类的问题。
我建议将这两种解决方案结合起来。
评论
我想不出它有用的场合。它对于像这样的循环很有用
while(do something);
或
for(init; do something; something else);
如果您经常在 IDE 中使用代码格式,这些类型的错误就会变得很明显。一些 IDE 也强调这是一个可能的错误。
在什么情况下这样做会有用吗?
有用?就像“让你的代码更干净、更清晰、更快、更易于维护”一样?一点也不。这很可能是糟糕的、令人困惑的代码。
但这不一定是良性的。由于引起副作用的方法,此类语句可以执行操作和/或更改状态,并且可以选择性地评估由于运算符短路而导致的方法。
if( a() && b() );
在这里,或者可以做一些事情,并且只有在为真时才会执行。a()
b()
b()
a()
至于为什么,我认为答案很简单,偏离定义的预期行为(例如,像 这样的语句)比开发人员编写糟糕代码的替代方案更糟糕。while(reader.read());
编写糟糕的代码总是可能的。重申一下,这几乎在任何情况下都是糟糕的代码。
if(a==b)
println("a equals b");
如果只有一行要执行,则可以使用不带 IF 语句的 IF 语句,因此通过使用 if they equal, execute 和 empty 语句...因此,它不会执行任何操作,然后返回到 IF 块之外的正常循环。{}
if(a==b);
评论
println("a now equals b");
如果使用语句,则如果条件为 true,则将执行 之后的第一条语句。如果 后面有一个块(带大括号),则它计入整个块。如果没有块,则仅计入一个语句。单个分号是空语句。你也可以从你的示例中编写代码,如下所示:if
if
if
if(a==b) {
;
}
我同意你的看法,这对人类来说没有用处。我怀疑它的存在是因为它简化了语言定义;例如,这意味着 an 之后的事物与 a 之后的事物 e 相同。if
while
可能的用例:
if (a==b);
else {
// Do something
}
不好,但有可能。
不过,我确实认为 Java 规范应该不允许空的 .if
评论
if (a==b) { // do nothing } else { doSomething(); }
这是在有更多的句法糖来区分表达式和语句的时代遗留下来的。
基本上,逗号用作列表项分隔符,因此分号用作“语句列表”分隔符。缺点在于处理列表中的 null 项和块中的 null 语句。
在项目列表中,Java 使用 explicit 关键字,但“null 语句”只是一个空行。允许空行的存在是从 C 继承的传统遗留下来的。null
为什么要这样做?特别是当你知道没有语句被执行时,语句:因为一些 if 语句有副作用:if
int c;
if ((c = in.read()) != -1);
是的,这不是最好的例子,但基本上它说从流中读取一个字节并且什么都不做。在某些极端情况下可能很有用,但即使这个例子不是最好的,它也说明了意图。我们希望在不意外执行任何语句的情况下感受到表达式的副作用。
Java 允许在允许语句块的任何地方使用空块。我确信将其作为所有块的一般规则可以简化编译器。
我同意这主要是导致难以找到的错误的原因。我总是在块周围使用大括号,即使只有一个语句,但 Java 允许你在任何时候用大括号制作块,所以使用大括号并不能让你免于这种命运。例如,我曾经浪费了 4 个小时试图找到这样的东西:
while (condition);
{
statement;
statement;
}
第一行末尾的分号是一个错别字,意外地使 while 循环的语句块为空。因为语法是有效的,所以程序编译和运行良好,只是不是我想要的方式。真的很难找到。
我能想到一种情况,允许你有空块是非常好的,这是这样的:
if (condition1) {
do_action_1();
}
else if (condition2) {
//nothing really to do in this case
}
else if (condition3) {
do_action2();
}
else {
do_action3();
}
在上面的示例中,您希望能够分离出各种条件。请记住,这些条件可能是重叠的,因此并不总是可以重新排列顺序。如果其中一个条件真的不需要做任何事情,那么 Java 允许你有一个空块是很好的。否则,当你真的不想做任何事情时,该语言将需要某种形式的“noop”方法来使用。
我个人更喜欢明确的“noop”语句——但这不是 Java 的定义方式。
末尾的分号,
if(a==b);只需在单行中完成语句,这意味着忽略条件的结果并从下一行
继续执行此代码很有用,另一方面有时会在程序中引入错误,例如案例
1。
a = 5;
b = 3;
if(a == b);
prinf(“A 和 B 相等”);
案例 2.
a = 5;
b = 5;
if(a == b);
prinf(“A 和 B 相等”);
会在屏幕上打印相同的输出...
评论
为什么?这是因为它对编译器编写者来说更容易。您不必在之后使用特殊情况来检查分号,并且具有允许的附加用法if(cond)
if (cond && maybeFunc())
;// Code here I want to ignore
尽管允许这样做实际上是一个糟糕的主意。允许然后添加案例来检查这一点更容易。
评论
我可以想到一个需要空语句的场景(不是条件,而是循环)。if
while
当程序只想从用户那里得到明确的确认才能继续时。当用户确认后的工作依赖于其他一些事情并且用户想要控制何时继续时,这可能是必需的。
System.out.println("Enter Y to proceed. Waiting...");
System.out.println("");
while(!(new Scanner(System.in).next().equalsIgnoreCase("Y")));
System.out.println("Proceeding...");
// do the work here
仅供参考,如果有这样的声明,它会产生或可以产生什么影响
考虑一段如下代码。
int a = 10;
if ((a = 50) == 50);
System.out.println("Value of a = " + a);
显然,在这种情况下,该语句确实会更改输出。因此,这样的声明可以有所作为。if
在这种情况下,这可能很有用,或者更准确地说对程序有影响。
如果你使用的是 Eclipse,你可以让它警告你这些语句:
jls 中的一些定义对此进行了解释(第 14 章):
块是语句
如上所述,a 是 ,而 是 ,而 是 。因此,无论需要其中任何一个,我们都可以插入一个 .Block
StatementWithoutTrailingSubstatement
StatementNoShortIf
Statement
Block
if 子句
虽然 和 -loops 也是如此,但我将使用 -语句。这些规则几乎是一样的。的语法描述可以在这里找到。for
while
if
if-statements
IfThenStatement:
if ( Expression ) Statement
IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement
IfThenElseStatementNoShortIf:
if ( Expression ) StatementNoShortIf else StatementNoShortIf
因此,我们可以在这里使用我们的块。
但是为什么它适用于 ; ?
;
定义为 (link),它也是 .因此,在条件代码片段中,如 和 循环,如果需要 或,我们可以用 a 替换 a。EmptyStatement
StatementNoShortIf
if-statement
Block
EmptyStatement
StatementNoShortIf
Statement
因此有效。if(Expression)EmptyStatement
为什么这不会给出错误?
很简单:如果 java 发现无效语法,它就会给出错误。但是完全有效的语法。相反,如果使用正确的参数启动,则会发出警告。可以禁用/启用的警告的完整列表列出了用于此目的的警告名称。因此,编译 or 将生成有关此的警告。if(Expression)EmptyStatement
javac
empty
-Xlint:all
-Xlint:empty
您的 IDE 也应该有一个选项来启用此类警告。
对于 eclipse,请参阅 @nullptr 的答案。在 IntelliJ 中,您可以按 ,进入搜索字段并启用警告(在图像中标记)Ctrl + Shift + A
empty body
这到底是干什么用的?
老实说,从极简主义的角度来看,它没有多大用处。通常有一种方法可以在没有“什么都不做”命令的情况下完成工作。这更像是个人喜好的问题,你是否愿意使用
if( a() && b() );
或
if( a() ) b();
这同样适用于使用其他情况。关于这个主题,要考虑的一个重要点是代码的可读性。在某些情况下,通过使用 no-op 使代码更具可读性。另一方面,在某些情况下,使用 - 上面的例子将计入后来的 IMO。EmptyStatement
EmptyStatement
在为课堂进行编程作业时,我正在使用 N x N 的涂鸦网格,并将随机涂鸦的特征与上面、下面、左边和右边的特征进行比较,我发现这是一个很好的用途,可以防止嵌套语句和潜在的边界异常。我的目标是尽量减少代码并避免嵌套 if 语句。
if (row == 0);
else (method (grid[row][col], grid[row-1][col]));
if (row == N-1);
else (method (grid[row][col], grid[row+1][col]));
if (col == 0);
else (method (grid[row][col], grid[row][col-1]));
if (col == N-1);<br>
else (method (grid[row][col], grid[row][col+1]));
在 A 和 B 之间进行某些操作的位置。method(Doodad a, Doodad b)
或者,您可以使用异常处理来避免这种语法,但它对我的应用程序有效且效果很好。
评论
if(row != 0) method (grid[row][col], grid[row-1][col]);
在不使用空语句的情况下将具有相同的效果。if
看这个:
int a,b,c = 0;
if(a == b){
c =1;
}
System.out.print(c);//1
所以,你可以这样写:
if (a == b)c=1;
但是,如果这段代码是这样的:
int a,b,c=0;
if (a != b){
}
if (a == b ){
c =1;
}
你可以这样写:
if(a != b);
if(a == b )c=1;
所以,你会知道做注意if(a != b);
if 中的分号表示 if 条件的终止,就像 java 中一样,被视为语句的结束,因此 if 之后的语句被执行。;
评论
if