89

我已经搜索过这个,但找不到答案,无论出于何种原因,我都不好意思问教授,因为当数百人盯着你看时的那种感觉......

无论如何,我的问题是有括号的重要性是什么?如果我省略它们可以吗?例子:

for (int i = 0; i < size; i++)  {
   a += b;
}

对比

for (int i = 0; i < size; i++)
   a += b;

我知道它们都可以工作,但是如果我省略括号(由于可见性,我倾向于做很多事情)会改变任何东西吗?正如我所说,我知道它有效,我测试了几十次,但现在我的一些大学作业越来越大,出于某种原因,我有一种非理性的恐惧,从长远来看,这会导致一些问题?有理由害怕吗?

4

16 回答 16

158

除了代码的可维护性之外,它根本不会改变任何东西。我见过这样的代码:

for (int i = 0; i < size; i++)
   a += b;
   System.out.println("foo");

这意味着:

for (int i = 0; i < size; i++)
   a += b;
System.out.println("foo");

...但应该是这样的:

for (int i = 0; i < size; i++) {
   a += b;
   System.out.println("foo");
}

就我个人而言,我总是将括号包括在内,以减少阅读或修改代码时混淆的可能性。

我工作过的每家公司的编码约定都要求这样做——这并不是说其他​​一些公司没有不同的约定……

以防万一你认为它永远不会产生影响:我必须修复一次错误,这几乎等同于上面的代码。它非常难以发现......(诚然,这是几年前,在我开始单元测试之前,这无疑会使诊断变得更容易)。

于 2011-11-05T12:46:04.993 回答
34

使用大括号使代码更易于维护和理解。所以你应该默认考虑它们。

我有时会跳过在保护子句上使用大括号以使代码更紧凑。我对此的要求是它们是if后跟跳转语句的语句,例如returnor throw。另外,我将它们放在同一行以引起对成语的注意,例如:。

if (!isActive()) return;

它们也适用于循环内的代码:

for (...) {
  if (shouldSkip()) continue;
  ...
}

以及来自不一定在方法体顶部的方法的其他跳转条件。

一些语言(如 Perl 或 Ruby)有一种条件语句,其中大括号不适用:

return if (!isActive());
// or, more interestingly
return unless (isActive());

我认为它等同于我刚才描述的内容,但语言明确支持。

于 2011-11-05T15:58:36.277 回答
12

没有区别。第二个版本的主要问题是你最终可能会这样写:

for (...) 
  do_something();
  do_something_else();

当您更新该方法时,认为do_something_else()在循环中调用了该方法。(这会导致令人头疼的调试会话。)

大括号版本没有第二个问题,而且可能更难发现:

for (int i=0; i<3; i++);
  System.out.println("Why on earth does this print just once?");

因此,除非您有充分的理由,否则请保留大括号,只需多敲几下键即可。

于 2011-11-05T12:44:43.763 回答
6

我认为松开花括号很好,如果您还使用自动格式,因为您的缩进总是正确的,所以很容易发现任何错误。

说把花括号去掉是不好的、奇怪的或不可读的,这是错误的,因为整个语言都是基于这个想法,而且它非常流行(python)。

但我不得不说,不使用格式化程序可能很危险。

于 2014-05-06T09:00:11.567 回答
6

对于大多数情况,到目前为止提到的答案都是正确的。但是从事物的安全角度来看,它也有一些缺点。在支付团队工作后,安全性是推动此类决策的一个更强大的因素。假设您有以下代码:

if( "Prod".equals(stage) )
  callBankFunction ( creditCardInput )
else
  callMockBankFunction ( creditCardInput )

现在假设由于某些内部问题,您的代码无法正常工作。你想检查输入。因此,您进行以下更改:

if( "Prod".equals(stage) )
  callBankFunction ( creditCardInput )
else
  callMockBankFunction ( creditCardInput )
  Logger.log( creditCardInput )

假设您解决了问题并部署了此代码(也许审阅者并且您认为这不会导致问题,因为它不在“Prod”条件之内)。神奇的是,您的生产日志现在打印客户信用卡信息,所有可以看到日志的人员都可以看到这些信息。上帝禁止他们中的任何人(出于恶意)获取这些数据。

因此,不给予支持和一点粗心的编码通常会导致安全信息的泄露。它也被CERT - Software Engineering Institure, CMU归类为 JAVA 中的漏洞。

于 2015-12-03T08:13:19.353 回答
4

如果您只有一条语句,则可以省略括号,因为声明代码块需要多条语句括号。

当您使用括号时,您正在声明一个代码块:

{

//Block of code
}

当您处于嵌套语句的情况下,括号也应该只与一个语句一起使用以提高可读性,例如:

for( ; ; )
  if(a == b) 
    doSomething()

如果没有必要,用括号写起来也更易读:

for( ; ; ) {
  if(a == b) {
    doSomething()
   }
}
于 2011-11-05T12:45:02.877 回答
4

如果您使用括号,您的代码将更具可读性。如果您需要在同一块中添加一些运算符,您可以避免可能的错误

于 2011-11-05T12:46:52.917 回答
3

使用方括号来证明代码不会受到以后的修改。我见过省略括号的情况,后来有人添加了一些代码并且当时没有放入括号。结果是他们添加的代码没有进入他们认为的部分。所以我认为答案是,鉴于未来对代码的更改,它是一种很好的做法。我已经看到软件组采用它作为标准,即出于这个原因,即使使用单行块也总是需要括号。

于 2011-11-05T12:45:55.993 回答
3

使用冗余大括号来声称代码更易于维护会引发以下问题:如果编写、想知道和进一步维护代码的人遇到之前描述的问题(与缩进相关或与可读性相关),也许他们根本不应该编程。 .

于 2017-02-27T05:58:52.563 回答
2

我对“总是大括号”组的更多支持。如果您省略了单语句循环/分支的大括号,请将语句与控制语句放在同一行,

if (condition) doSomething();
for(int i = 0; i < arr.length; ++i) arr[i] += b;

这样当身体膨胀时就更难忘记插入牙套了。不过,无论如何都要使用卷曲。

于 2011-11-05T14:17:54.710 回答
2

如今,很容易重新缩进代码以找出哪个代码块在哪个iffor/while中。如果你坚持认为重新缩进很难,那么放在错误缩进位置的括号同样会让你感到困惑。

for(int i = 0; i < 100; i++) { if(i < 10) {
    doSomething();
} else { for(int j = 0; j < 5; j++) {
        doSomethingElse();
    }
}}

如果你到处这样做,你的大脑很快就会崩溃。即使使用括号,您也依赖缩进来直观地找到代码块的开始和结束。

如果缩进很重要,那么您应该已经以正确的缩进编写代码,因此其他人不需要重新缩进您的代码即可正确阅读。

如果你想争辩说前面的例子太假/刻意,括号是用来捕捉粗心的缩进问题(尤其是当你复制/粘贴代码时),那么考虑一下:

for(int i = 0; i < 100; i++) {
    if(i < 10) {
    doSomething();
}
else {
    for(int j = 0; j < 5; j++) {
        doSomethingElse();
    }
}

是的,它看起来不像前面的例子那么严重,但是你仍然会被这种缩进弄糊涂。

恕我直言,编写代码的人有责任检查代码并确保在继续执行其他操作之前正确缩进。

于 2017-11-22T08:28:09.077 回答
1

结果明智,这是一回事。

只有两件事需要考虑。

- 代码可维护性
- 松散耦合的代码。(可能会执行其他操作。因为您尚未指定循环的范围。)

注意:在我的观察中,如果它在循环中循环。没有大括号的内环也是安全的。结果不会改变。

于 2015-07-31T03:48:47.930 回答
1

如果循环内只有一个语句,则它是相同的。

例如看下面的代码:

for(int i=0;i<4;i++)
            System.out.println("shiva");

我们在上面的代码中只有一个语句。所以没问题

for(int i=0;i<4;i++)
            System.out.println("shiva");
            System.out.println("End");

这里我们有两个语句,但只有第一个语句进入循环,而不是第二个语句。

如果您在单个循环下有多个语句,则必须使用大括号。

于 2015-11-04T07:28:49.423 回答
1

如果删除大括号,它只会读取第一行指令。不会读取任何额外的行。如果您有超过 1 行要执行的指令,请使用大括号 - 否则将引发异常。

于 2017-01-06T04:30:37.360 回答
0

重新格式化代码也应该是一种反射……这当然适用于专业团队中的专业程序员

于 2017-02-27T06:00:59.643 回答
0

最好在任何地方都使用花括号,因为调试这将是一个非常麻烦的简单事实。但另一方面,一行代码不一定需要括号。希望这可以帮助!

于 2017-10-29T19:46:40.030 回答