在java中使用/练习使用括号的最佳方式



在使用Sonar静态代码分析器时,我发现Sonar在使用括号方面的一些令人困惑的语句(可能只有我自己)。

下面是Sonar说去掉无用括号的几个代码片段:

line>1  String auth = "Basic "+ com.somepackge.someMethod(((String) (parent.proxyUsername+ ":" + parent.proxyPassword)));
line>2  return rawtime.length() > 3 ? (rawtime.substring(0, rawtime.length() - 2) + rawtime.substring(rawtime.length() - 2, rawtime.length()).toLowerCase()) : rawtime;

尽管我已经用下面的线代替了上面的线,以保持声纳的平静:):

Line>3 String auth = "Basic "+ com.somepackge.someMethod((String) (parent.proxyUsername+ ":" + parent.proxyPassword));
Line>4 return  rawtime.length() > 3 ? rawtime.substring(0, rawtime.length() - 2) + rawtime.substring(rawtime.length() - 2, rawtime.length()).toLowerCase() : rawtime;

所以讨论这个问题的原因是:

  1. 实际上,使用大括号是减少混淆的方法,所以为什么要删除这些括号。

  2. 用java编写任何复杂语句时,使用括号的最佳方式是什么。

我认为

(String) (parent.proxyUsername+ ":" + parent.proxyPassword)

这部分代码应该有大括号以避免混淆,但Sonar所期望的是:

   (String) parent.proxyUsername+ ":" + parent.proxyPassword

任何建议都会很有帮助。我得到了一些关于这个问题的链接,但这些都没有多大帮助。

第一个片段

String auth = "Basic "+ someMethod(((String) (parent.proxyUsername+ ":" + parent.proxyPassword)));

您可以将其重写为:

String auth = "Basic "+ someMethod(parent.proxyUsername+ ":" + parent.proxyPassword);

因为字符串串联运算符已经进行了字符串转换。除非您希望在proxyUsernameproxyPassword不是字符串时抛出ClassCastException

第二个片段

return rawtime.length() > 3 ? (rawtime.substring(0, rawtime.length() - 2) + rawtime.substring(rawtime.length() - 2, rawtime.length()).toLowerCase()) : rawtime;

括号确实没有必要,但这句话很难读懂。如果你想继续使用三元运算符,我建议你把语句分成几行:

return rawtime.length() > 3
       ? rawtime.substring(0, rawtime.length() - 2) + rawtime.substring(rawtime.length() - 2, rawtime.length()).toLowerCase()
       : rawtime;

或者你可以恢复条件:

return rawtime.length() <= 3 ? rawtime :
       rawtime.substring(0, rawtime.length() - 2) + rawtime.substring(rawtime.length() - 2, rawtime.length()).toLowerCase();

Line 1有多余的括号,但Line 2的括号为三元语句增加了清晰度。

2中的额外括号是否有用还有待商榷,但没有理由不删除1中多余的括号。

一般来说,最好使用额外的括号来表达您对代码应该做什么的意图,或者消除事情发生顺序中的歧义。

这两个版本之间存在语义差异:

(String) (parent.proxyUsername+ ":" + parent.proxyPassword)

(String) parent.proxyUsername+ ":" + parent.proxyPassword

在第一个集合中,()的第二个集合已经计算为String,隐式调用parent.proxyUsername.toString()proxyUsername转换为String。因此,演员阵容是多余的,应该删除IMHO。第二个版本将parent.proxyUsername强制转换为String,如果它没有运行时类型String(仅当它被声明为String是强制转换冗余时),则会引发异常。

我同意第2行和第4行读起来很复杂,不管它们是否有多余的大括号。如果你想要清晰,请重写。也就是说,多余的牙套有时对清晰度有好处,IMHO,我偶尔也会用。

最好的方法是将要转换的类放在一个括号中,然后将整个要转换的部分放在另一个括号内,然后将这整个代码包括在一个容器括号中,您的代码应该是这样的,例如((String)(x+y))。

我希望这有帮助,谢谢。

最新更新