锁定老帖子 主题:单命令行下,if 必须加"{}" 的问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (16)
|
|
---|---|
作者 | 正文 |
发表时间:2011-05-31
你该明白你在公司写的代码不是永远只有你个人来维护!你确实对你自己的代码很熟!但你也有离开的一天,别人来接的时候就体现出{}重要性了!
|
|
返回顶楼 | |
发表时间:2011-05-31
最后修改:2011-05-31
加上可以减少很多维护风险,仅此一个理由就够了吧?
if (a > 0) return 1; else if (a < 0) return -1; else (a == 0) return 0; 如果是确定不会有其它情况,那还不如直接三目: return a>0 ? 1 : (a<0 ? -1 : 0); 问题是,以后维护的人看这行代码时会多蛋疼…… |
|
返回顶楼 | |
发表时间:2011-05-31
不要给自己的懒找借口,也不要认为行号少了几十就显得多高明。
幸好LZ没有批判 (a > 0) 多了两个空格占地方 |
|
返回顶楼 | |
发表时间:2011-05-31
工具限制思路。
在java里,for、if表达式本身都不返回值,它们的作用只是在适当的情况下执行后面语句,因此,执行这些语句必然要产生一定的效果,例如给变量赋值成计算后的值,换句话说,这些语句必然产生side effect。 那么“有没有side effect”和“要不要加大括号”有什么联系呢? 举例,根据对一个现有的list每项加一得到新的list,用java实现是: List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); List<Integer> newList = new ArrayList<Integer>(); for(Integer item:list){ //注意,这里以后还可以加一些与生成newList无关的其它代码,比如,计算item累加值。 newList.add(item + 1); } 用scala实现是: val list = List(1,2,3) val newList = for(item <- list)yield{ // 注意这里,无论下面代码以后有多长,都与计算新元素有关。 // 如果以后有其它需求,使用新的for语句来做。 item + 1 } 随着项目的开展,对于java代码,常常需要往已有的for、if语句里添加新代码来做其它事情,如果事先不加大括号,也会编译通过,但得到的运行结果又不是预期的,这样发现问题的成本比较高。 也就是说,java这种有side effect的if/for语句,以后难免要膨胀,早加大括号也许会减少修复bug的成本,相比之下,上面scala风格的if/for的功能是单一、明显、可控的。 |
|
返回顶楼 | |
发表时间:2011-05-31
最后修改:2011-05-31
这种规范问题讨论起来仁者见仁,智者见智,不过我认为必须加上,java语言就在其规范性特强,所有人按照编码规范编码,最好的结果就是大家写一个功能,一个思路的情况下,代码一模一样,这才是好代码,这样极易维护,来个人就能看明白,思想上要创新,规范上创新有什么用,少写两个括号就能显出你牛b吗?感觉不写括号就不够严谨。
要是不加括号,多行时候必须加,1行时候不加,你自己看着不别扭吗?手动缩进多累啊。 最后举个例子,你可以举出100多条早上起来不叠被的好处,有10000个人赞同你,但是军队还是要叠被,叠的还很齐;企业就是这样,你好处再多,企业还是需要规范,需要管理的。不加括号就像不叠被的新兵(举例而已),个人能力再强,不遵守规范也不是好兵(除非你们公司规定就不加)。 |
|
返回顶楼 | |
发表时间:2011-05-31
雪飘寒 写道 这种规范问题讨论起来仁者见仁,智者见智,不过我认为必须加上,java语言就在其规范性特强,所有人按照编码规范编码,最好的结果就是大家写一个功能,一个思路的情况下,代码一模一样,这才是好代码,这样极易维护,来个人就能看明白,思想上要创新,规范上创新有什么用,少写两个括号就能显出你牛b吗?感觉不写括号就不够严谨。
要是不加括号,多行时候必须加,1行时候不加,你自己看着不别扭吗?手动缩进多累啊。 最后举个例子,你可以举出100多条早上起来不叠被的好处,有10000个人赞同你,但是军队还是要叠被,叠的还很齐;企业就是这样,你好处再多,企业还是需要规范,需要管理的。不加括号就像不叠被的新兵(举例而已),个人能力再强,不遵守规范也不是好兵(除非你们公司规定就不加)。 觉的这个才是问题的本质,加不加并不会影响运行的效率,编译器都进行了相应的优化 |
|
返回顶楼 | |
发表时间:2011-05-31
最后修改:2011-05-31
好吧看代码,把下面两段代码粘到eclipse中你就会知道了
public class Test { public static void main(String[] args) { if (true) { String i = new String("Test"); } } }上面的编译正确 public class Test { public static void main(String[] args) { if (true) String i = new String("Test"); } }上面的编译错误 至于原因请高人来回答 |
|
返回顶楼 | |
发表时间:2011-05-31
lion1354 写道
好吧看代码,把下面两段代码粘到eclipse中你就会知道了
public class Test { public static void main(String[] args) { if (true) { String i = new String("Test"); } } }上面的编译正确 public class Test { public static void main(String[] args) { if (true) String i = new String("Test"); } }上面的编译错误 至于原因请高人来回答
对于if后面的{},我的实践,并且使用语法检测工具配置的策略: 我的实践:什么时候不写{},其他时候都必须写
|
|
返回顶楼 | |
发表时间:2011-06-01
最后修改:2011-06-01
哥, 别蛋疼, 喝几量白酒, 然后, 来修改你的代码, 如果在单行if 一直能修改对, 那你就不需要遵循这个狗屁规则了。
这是我某年曾经犯过的错误, 从此以后{}从没有离开过if~ |
|
返回顶楼 | |
发表时间:2011-06-01
最后修改:2011-06-01
lion1354 写道 好吧看代码,把下面两段代码粘到eclipse中你就会知道了
public class Test { public static void main(String[] args) { if (true) { String i = new String("Test"); } } }上面的编译正确 public class Test { public static void main(String[] args) { if (true) String i = new String("Test"); } }上面的编译错误 至于原因请高人来回答 嘛,这个的理由很简单:因为局部变量声明不是“语句”。 这是Java语言规范里非常搞笑的一个地方:请看Java语言规范第三版18.1所指定的语法规则中的几条: Block: { BlockStatements } BlockStatements: { BlockStatement } BlockStatement : LocalVariableDeclarationStatement ClassOrInterfaceDeclaration [Identifier :] Statement LocalVariableDeclarationStatement: [final] Type VariableDeclarators ; Statement: Block assert Expression [ : Expression] ; if ParExpression Statement [else Statement] for ( ForControl ) Statement while ParExpression Statement do Statement while ParExpression ; try Block ( Catches | [Catches] finally Block ) switch ParExpression { SwitchBlockStatementGroups } synchronized ParExpression Block return [Expression] ; throw Expression ; break [Identifier] continue [Identifier] ; StatementExpression ; Identifier : Statement MethodBody: Block 方法体必须是一个block。 Block是由花括号包围的零或多个BlockStatement。 BlockStatement可以是局部变量声明,或者类/接口声明(注:这样的类或接口被称为“局部类”(local class)“局部接口”(local interface)),或者是可选带label的语句Statement。 语句有若干中可能,其中一种是if语句;if语句的then分支必须是一个Statement。 关注点是:LocalVariableDeclarationStatement虽然叫做“Statement“,但在语法规则中它却不是一种”Statement“。所以说根据这个规则,局部变量声明就不是语句,自然也就不能单独出现在if的then分支位置上。被花括号包围起来的话它就是一个Block了,而Block是Statement的一种所以没问题。 槽点:叫做“语句”但却不是语句的局部变量声明。 顺带一提,NS提醒我,在javac里代表局部变量声明的节点类型是JCVariableDecl,该类继承了代表了语句的JCStatement类;但是,javac仍然会按照语法规范来检查…所以if的then分支上还是不能单独放一个局部变量声明 =_=||| 想看源码的请点: http://hg.openjdk.java.net/jdk6/jdk6/langtools/file/tip/src/share/classes/com/sun/tools/javac/tree/JCTree.java |
|
返回顶楼 | |