2011-09-28 82 views
2

我使用PMD来检查我的代码。在大多数情况下,它给了我很多有用的提示,但我无法弄清楚在以下情况下可以改进哪些方面。Java可折叠if语句

原始代码看起来是这样的:

if ((getSomething() != null && getSomethingElse() != null) 
    || (getSomething() == null && getSomethingElse() == null)) 
{ 
    ... 
} 

PMD告诉我:

有时是两个“如果”语句可以用一个布尔短路运营商分离的 条件得到巩固。

为简单起见,我们只需使用a和b作为布尔变量。那么这段代码看起来是这样的:

if ((!a && !b) || (a && b)) 

这可以转化为下列之一:

if ((!a || b) && (a || !b)) 
if (!(a^b)) 

最后

if (a==b) 

所以我简化我的代码

if ((getSomething() == null) == (getSomethingElse() == null)) 

然而,PM D不断抱怨(实际上关于所有三个版本)。这是一个假阳性还是有更好的方式来编写if条件?

+2

你确定你的代码中没有另外的_if_语句吗? PMD抱怨_two_如果陈述,而不是一个比必要更复杂 – michael667

+0

我想不出更好的最终版本(这是我的代码)。 * if里面有什么* if - 块里面有另外一个if吗? – Bohemian

+0

我刚刚在JSR305规范中发现了@ javax.annotations.Nonnull和@ javax.annotations.Nullable注解。我使用的是'com.google.code.findbugs:1.3.9'中的Google实现。它大大清理了我的代码,Intellij IDEA auto根据这些注释生成代码和警告。 –

回答

3

的问题是不同的东西。 if语句在里面另一个唯一的代码,如果(代码来自验证方法):

if (...) 
{ 
    ... 
} 
else if (...) 
{ 
    ... 
} 
else if (...) 
{ 
    if ((getSomething() == null) == (getSomethingElse() == null)) 
    { 
     ... 
    } 
} 

什么PMD消息指,是我可以结合的条件下,最后还有,如果和内如果子句:

if (...) 
{ 
    ... 
} 
else if (...) 
{ 
    ... 
} 
else if (... && ((getSomething() == null) == (getSomethingElse() == null))) 
{ 
     ... 
} 

但是,我不知道,如果我这样做,是因为原来的版本似乎更清晰的了解。

2
if ((a != null) && (b != null) && (a==b)) 

..although个人而言,我会做的空检查之前,这个if语句,所以我可以处理一个== NULL和b == NULL的情况下单独

+0

这是关于分别处理'null'情况的一个很好的建议。通过这种方式,您可以抛出特定的NPE来告诉用户哪一个是'null'或者以特定方式处理它们。 –

+0

不应该是'|| (A == B)'? – Gandalf

+0

@Gandalf我不这么认为....由于JRE处理if语句从左到右查找逻辑真或假,我发布的if语句将如下评估: 1)'a'是否为空?是的,向右移动。如果是错误的,整个评估不可能是真实的,因此请停止评估。 2)'b'是否为空?是的,向右移动。如果是错误的,整个评估不可能是真实的,因此请停止评估。 3)现在我们知道'a'和'b'都不是null,我们可以安全地评估'a == b' – claymore1977

1

问题是大块条件很难推理。

OTOH,不是每一个警告PMD发出需要注意的 - 考虑投资回报率。是否值得重构或重组以使其更清洁?相同的功能可以以不同的方式处理吗?

如果不值得,请不要打扰。

+0

我不认为我会改变我的代码,但它仍然是有趣的发现,什么可以“改善”。 – martin

+0

即使我们听到建议并立即忽略它,它总是这样;) –