2013-04-26 38 views
15

这是我认为的java纯粹主义者之一。我最近有一个方法来执行String值的自定义分析到布尔值的问题。一个很简单的任务,但由于某些原因如下方法是空的情况下抛出一个NullPointerException ...布尔型的NullPointerException

static Boolean parseBoolean(String s) 
{ 
    return ("1".equals(s) ? true : ("0".equals(s) ? false : null)); 
} 

该方法的返回类型布尔为什么或如何能一个NullPointerException异常被抛出? 通过调试,似乎在嵌套的内联条件语句计算为null并将外部内联条件返回null的时候抛出异常,但我再次无法解释原因。

最后,我放弃了,并重写了方法如下,符合市场预期,其工作原理:

static Boolean parseBoolean(String s) 
{ 
    if ("1".equals(s)) return true; 
    if ("0".equals(s)) return false; 

    return null; 
} 

下面的代码是两者之间的半路上,也按预期工作:

static Boolean parseBoolean(String s) 
{ 
    if ("1".equals(s)) return true; 

    return "0".equals(s) ? false : null; 
} 
+2

+1对于一个不错的“益智游戏” – NilsH 2013-04-26 10:35:34

+0

@NilsH感谢+1和解决方案! – Robin 2014-01-27 11:25:35

回答

13

这也适用于:

static Boolean parseBoolean(String s) 
{ 
    return ("1".equals(s) ? Boolean.TRUE : ("0".equals(s) ? Boolean.FALSE : null)); 
} 

所以,你得到的NPE是由于自动装箱,因为三元运算符使用boolean导致表达式的结果作为一个boolean被处理的原因。 null的解除导致NPE。

+1

+1做得好。不是一个原来认为看代码的东西。 – 2013-04-26 09:58:46

+0

好答案@Nils - 那个滑的小恶魔!我没有想过使用布尔常量。 – Robin 2013-08-05 11:07:01

8

我建议?不要返回Boolean,返回boolean并抛出一个异常:

static boolean parseBoolean(String s) 
{ 
    if ("1".equals(s)) return true; 
    if ("0".equals(s)) return false; 

    throw new IllegalArgumentException(s + " is not a boolean value."); 
} 

采用类似的做法都有助于避免不小心引用空Boolean对象。请参阅excellent answer from NilsH以查看原始方法抛出异常的原因。

+1

我同意。以后快速遇到NPE会更好。如果需要“三态”解决方案,布尔有它的用处。 – NilsH 2013-04-26 10:27:12

+0

这是一个三态条件,所以我真的不应该为期望值抛出异常! 反正也不是异常处理更贵? – Robin 2013-08-05 11:02:43

2

有趣但没有答案告诉你为什么这种情况发生在第一位。

这与三元表达有关。

编译器将null解释为对Boolean的空引用,对Boolean应用自动装箱/拆箱规则(对null)=>在运行时会出现NullPointerException。

+2

我认为你必须重新阅读答案;) – NilsH 2013-04-26 10:04:52

+1

@NilsH可能在写作时错过了你的这一部分。 :)从我+1。 – Eugene 2013-04-26 10:05:52