如果我在Java中省略花括号可以吗?[关闭]


83

我已经搜索过了,但是找不到答案,无论出于什么原因,我都感到羞愧,无法问教授,因为数百人盯着你的那种感觉……

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

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

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

我知道它们都可以使用,但是如果我省略了括号(由于能见度,我倾向于做很多事情)是否会改变任何东西?正如我所说,我知道它有效,我对其进行了数十次测试,但是现在我的一些单项作业越来越大,出于某种原因,我出于非理性的担心,从长远来看,这会引起一些问题吗?有理由担心吗?


我始终使用代码格式化程序来提高可读性,因为这可以解决造成混淆的许多潜在原因。这可以使使用大括号多余
Peter Lawrey

Answers:


146

除了代码的可维护性之外,它什么都不会改变。我看过这样的代码:

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");
}

我个人总是将方括号括起来,以减少在阅读或修改代码时造成混淆的可能性。

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

以防万一,您认为这永远不会有所作为:我不得不修复一次错误,该错误与上面的代码相当。很难发现……(诚然,这是几年前,在我开始进行单元测试之前,毫无疑问,这使诊断变得更加容易)。


12
@vedran:所以您知道这个问题,但是您只是假设它永远不会咬你?每个阅读您的代码的人都会知道会发生什么?我只是说-我使用的编码约定中有这些要求的原因:)
Jon Skeet

12
我只是觉得自己像是一个被讽刺者嘲笑的私人。是的,虽然这对我来说更方便,但其他人却感到烦恼和麻烦。从现在开始,我将确保在所有地方使用括号。
vedran 2011年

13
@vedran很好的隐喻,除了Jon Skeet并不勤快,他是总司令:-)
stivlo 2011年

5
@stivlo哦,我确定他的宽容会原谅我的不服从;)就我个人而言,我确实在声明之后加上括号,因为它是我见过的每篇编码指南的一部分,但我认为今天的论点相当微弱。随处使用自动代码格式化,无论如何您都永远不会看到其第一形式的代码,如果缩进正确,则括号内不会提供任何其他信息。
Voo

4
始终使用花括号的更多说法:imperialviolet.org/2014/02/22/applebug.html
MrTJ 2014年

32

使用花括号使代码更易于维护和理解。因此,默认情况下应考虑它们。

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

if (!isActive()) return;

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

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

以及来自方法的其他跳转条件,这些跳转条件不一定位于方法主体的顶部。

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

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

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


7
如果没有花括号,循环内的+1保护子句通常会更清晰。
维卡里(Viccari)2012年

2
商定了保护条款。我认为使代码更具可读性,并实际上增加了可维护性。但是,已接受的答案提出的观点是非常有效的,因此我将省略括号到保护子句的限制。
克里斯克

11

没有区别。第二个版本的主要问题是您可能最终会编写以下代码:

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?");

因此,除非有充分的理由,否则请保持大括号,这仅是几次击键。


3
第一点是好的,但第二点是错误的。大括号版本仍然可能存在该问题。为(int i = 0; i <3; i ++); {System.out.println(“为什么只打印一次?”); }。我知道,因为我总是使用花括号,但有时会错误地添加多余的分号。
emory

3
括号版本可以使用它,但是如果括号在同一行上,则更容易看到。确实,在下一行中将大括号括起来,真是令人讨厌。

对我而言,第二个版本与第一个版本一样重要,因为查看第二个版本几乎不可能发现错误所在,除非您实际运行它以查看世界上正在发生的事情。开发人员花费大量时间调试像这样的代码,如果引入了那些弯腰的括号,这些代码很容易被发现。对我来说,省略那些曲折的括号不仅是样式问题,而且是可能的错误代码的良好指示。
CallMeJun

5

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

说出大括号是不好的,奇怪的或不可读的,这是错误的,因为整个语言都基于该思想,并且非常流行(python)。

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


缩进在Python中很重要。在Java,C,C ++或其他C样式语言中,则不是。
Christopher Schneider

1
@ChristopherSchneider就是这样。
马塔·玛雅(MátéMagyar),

5

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

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

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

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

假设您解决了问题并部署了此代码(也许是审阅者,并且您认为这不会导致问题,因为它不在“ Prod”条件下)。神奇的是,您的生产日志现在可以打印所有可以查看日志的人员可见的客户信用卡信息。如果其中任何一个人(出于恶意目的)掌握了这些数据,上帝就会禁止。

因此,不加括号和稍加粗心的编码通常会导致违反安全信息。CERT-软件工程研究所(CMU)在JAVA中也将该漏洞分类为漏洞。


我认为这首先是一个非常糟糕的设计,但这一点是正确的。
Christopher Schneider

4

如果只有一条语句,则可以省略方括号,对于声明一个代码块而言,一个以上的语句方括号是必需的。

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

{

//Block of code
}

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

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

如果不需要,也可以用方括号括起来:

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


3

将来使用括号将使代码免于以后的修改。我已经看到了省略括号的情况,后来有人添加了一些代码,但当时并没有放入括号。结果是他们添加的代码没有进入他们认为正确的部分。因此,我认为答案是,鉴于将来对代码的更改,它的优良作法。我已经看到软件组将其作为标准,即出于这个原因,即使单行代码也总是需要使用括号。


我同意这一点。括号不适合您。他们是给在你后面的人的。有好几次,我一直在维护自己不熟悉的代码,没有使用方括号,并且缩进不良。在此阶段,我可能正在修复错误,因此很高兴知道应该发生什么。省略花括号使其不那么明显,我必须逐步遍历代码,浪费时间。
Christopher Schneider

2

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

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

这样,当身体膨胀时就很难忘记插入牙套。尽管如此,还是要使用冰壶。


2

使用多余的花括号来声明代码更可维护,这引发了以下问题:如果编写,怀疑和进一步维护代码的人遇到了像前面所述的问题(与缩进相关或与可读性相关),那么他们根本不应该编程。 。


1

结果明智,是一回事。

仅需考虑两件事。

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

注意:根据我的观察,如果是循环中的,则为循环。不带括号的内环也是安全的。结果不会改变。


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");

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

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


1

如果您删除括号,它将仅读取指令的第一行。任何其他行都不会被读取。如果要执行的指令多于1行,请使用大括号-否则将引发异常。


1

如今,它很容易再次缩进代码,找出哪些代码块中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();
    }
}

是的,它看起来没有以前的示例那么严重,但是您仍然会对这种缩进感到困惑。

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


0

还应该重新格式化代码……这当然是针对专业团队中的专业程序员的


0

可能最好在各处都使用花括号,因为简单的事实是调试它会带来极大的麻烦。但是从其他方面来说,一行代码不一定需要括号。希望这可以帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.