如果我在Java中省略花括号,这样可以吗?

ved*_*ran 77 java coding-style brackets

我已经搜索了这个,但无法找到答案,无论出于何种原因,我太羞于问教授,因为有数百人盯着你的感觉......

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

for (int i = 0; i < size; i++)  {
   a += b;
}
Run Code Online (Sandbox Code Playgroud)

VS

for (int i = 0; i < size; i++)
   a += b;
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 131

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

for (int i = 0; i < size; i++)
   a += b;
   System.out.println("foo");
Run Code Online (Sandbox Code Playgroud)

这意味着:

for (int i = 0; i < size; i++)
   a += b;
System.out.println("foo");
Run Code Online (Sandbox Code Playgroud)

......但应该是这样的:

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

我个人总是包括括号,以减少阅读或修改代码时混淆的可能性.

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

并且万一你认为它永远不会有所作为:我必须修复一次错误,这几乎与上面的代码相同.很难发现......(不可否认,这是几年前,在我开始进行单元测试之前,这无疑会使诊断变得更容易).

  • @vedran很好的比喻,除了Jon Skeet没有sarge,他是总司令:-) (12认同)
  • 我只觉得像一个私人被一个sarge谈到了.是的,虽然它对我来说更方便,但我的团队中的其他人觉得它很烦人且有问题.从现在开始,我将确保使用括号. (11认同)
  • @vedran:所以你知道这个问题,但你只是假设它永远不会咬你?阅读代码的每个人都知道会发生什么?我只是说 - 有一个原因,为什么他们在我使用的编码约定中需要:) (10认同)
  • @stivlo哦,我确定他的恩典会赦免轻微的不服从;)我个人在发言后加上括号,因为它是我见过的每一个编码指南的一部分,但我认为今天这是一个相当弱的论点.在任何地方使用自动代码格式化,无论如何都不应该以第一种形式看到代码,如果缩进是正确的,括号不会提供任何其他信息. (5认同)
  • 使用ALWAYS大括号的更多论据:https://www.imperialviolet.org/2014/02/22/applebug.html (4认同)
  • 或者...不要让 python 开发人员处理 java 代码;-) (2认同)

Jor*_*dão 32

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

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

if (!isActive()) return;
Run Code Online (Sandbox Code Playgroud)

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

for (...) {
  if (shouldSkip()) continue;
  ...
}
Run Code Online (Sandbox Code Playgroud)

以及来自不一定位于方法体顶部的方法的其他跳转条件.

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

return if (!isActive());
// or, more interestingly
return unless (isActive());
Run Code Online (Sandbox Code Playgroud)

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

  • 内部循环中的+1保护子句通常更清晰,没有花括号. (6认同)
  • 同意保护条款.在我看来,使代码更具可读性,并且实际上提高了可维护性.接受的答案所提出的要点非常有效,所以我将限制省略括号来保护条款. (2认同)

Mat*_*Mat 11

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

for (...) 
  do_something();
  do_something_else();
Run Code Online (Sandbox Code Playgroud)

当你更新该方法时,认为do_something_else()在循环内部调用.(这会导致令人头疼的调试会话.)

还有第二个问题是支架版本没有,它可能更难发现:

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

除非你有充分的理由,否则请保持支撑,这只是几次击键.

  • 第一点是好的,但第二点是错误的.支架版本仍然可能有这个问题.for(int i = 0; i <3; i ++); {System.out.println("为什么只打印一次?"); }.我知道,因为我总是使用大括号,但有时会错误地添加额外的分号. (3认同)
  • 支架版本可以拥有它,但如果支架在同一条线上则更加明显.事实上,在下一行的支撑上,它几乎是令人讨厌的. (3认同)

小智 5

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

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

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


小智 5

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

if( "Prod".equals(stage) )
  callBankFunction ( creditCardInput )
else
  callMockBankFunction ( creditCardInput )
Run Code Online (Sandbox Code Playgroud)

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

if( "Prod".equals(stage) )
  callBankFunction ( creditCardInput )
else
  callMockBankFunction ( creditCardInput )
  Logger.log( creditCardInput )
Run Code Online (Sandbox Code Playgroud)

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

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