2014-05-02 60 views
3

我写了一些代码;这里的相关片段:三元运算符在条件不满足时评估条件语句

@NonNullByDefault 
public class Score<NUMERAL, LITERAL> 
{ 
    protected NUMERAL value; 
    @Nullable 
    protected LITERAL literal; 
    [...] 

我已经重写我的equals()方法如下:

@Override 
public boolean equals(@Nullable Object object) 
{ 
    if(object == null) return false; 
    if(object == this) return true; 

    if(object instanceof Score) 
    { 
     return ((Score<NUMERAL, LITERAL>) object).getValue().equals(value) && 
       literal == null ? ((Score<NUMERAL, LITERAL>) object).getLiteral() == null : literal.equals(((Score<NUMERAL, LITERAL>) object).getLiteral()); 
    } 
    return false; 
} 

基本上,这个想法是,一个Score可能只有一个数值在这种情况下,literal为空。我已经写了一些单元测试,并获得与下面的代码一个空指针异常:

[....] 
Score<Float, String> score = new Score<>(0.0f); 
Score<Float, String> anotherScore = new Score<>(1.0f, "One"); 
[....] 

assertFalse(score.equals(anotherScore)); 

如果我没有记错的话,应该不会短切在equals防止&&后从任何作为第一个表达式执行已经是false?此外,为什么是例外?由于条件是正确的,我期望评估三元的表达式并跳过条件表达式。从我在规范中读到的内容来看,这应该是行为。此外,我发现了这个问题:Java ternary (immediate if) evaluation这应该为我的思维过程提供更多的杠杆作用。

也许我忽略了一些相当明显的东西,但我没有想法。也许你可以帮忙?

回答

3

它短路好,但不是你想要的方式。 &&具有比三元?:一个更高的优先级 - 因此,本(压痕,换行符和评论添加到澄清)

((Score<NUMERAL, LITERAL>) object).getValue().equals(value) && 
literal == null 
    ? ((Score<NUMERAL, LITERAL>) object).getLiteral() == null 
    : literal.equals(((Score<NUMERAL, LITERAL>) object).getLiteral()) 

实际上意味着此:

//the first line as a whole is the condition for ?: 
((Score<NUMERAL, LITERAL>) object).getValue().equals(value) && literal == null 
    ? ((Score<NUMERAL, LITERAL>) object).getLiteral() == null 
    : literal.equals(((Score<NUMERAL, LITERAL>) object).getLiteral()) 

这意味着在实践中,如果第一部分的条件是falseliteralnull,您自动输入:表达式的一部分,您调用literal.equals的一部分,导致NullPointerException

的修复很简单:加括号来告诉Java中,你要的东西要评估哪种方式:

((Score<NUMERAL, LITERAL>) object).getValue().equals(value) && 
(literal == null 
    ? ((Score<NUMERAL, LITERAL>) object).getLiteral() == null 
    : literal.equals(((Score<NUMERAL, LITERAL>) object).getLiteral())) 
+0

@ durron597,OP似乎是一个编码器谁绝对可以明白这一点为自己,但我想它赢得不痛。包括它马上。 – kviiri

+1

我同意,但未来的读者可能有这个问题,但可能不是那么聪明:)。无论如何我还是在评论之前加了一句话;感谢您进行编辑。 – durron597

+0

@ durron597,没问题,你把它带出来很好。 – kviiri