210

我有以下代码:

Boolean bool = null;

try 
{
    if (bool)
    {
        //DoSomething
    }                   
} 
catch (Exception e) 
{
    System.out.println(e.getMessage());             
}

为什么我对布尔变量“bool”的检查会导致异常?当它“看到”它不是真的时,它不应该直接跳过 if 语句吗? 当我删除 if 语句或检查它是否为空时,异常消失了。

4

9 回答 9

509

如果您不喜欢额外的空检查:

if (Boolean.TRUE.equals(value)) {...}
于 2013-09-13T15:36:34.273 回答
193

当您有 aboolean时,它可以是truefalse。但是,当您拥有 a 时Boolean,它可以是Boolean.TRUEBoolean.FALSE也可以是null任何其他对象。

在您的特定情况下,您的Booleanisnullif语句会触发隐式转换,boolean从而产生NullPointerException. 您可能需要:

if(bool != null && bool) { ... }
于 2012-06-12T21:42:26.910 回答
100

使用Apache BooleanUtils

(如果峰值性能是您项目中最重要的优先事项,那么请查看不需要包含外部库的本机解决方案的其他答案之一。)

不要重新发明轮子。利用已经构建和使用的内容isTrue()

BooleanUtils.isTrue( bool );

检查一个Boolean值是否为真,null通过返回来处理false

如果您不限于“允许”包含的库,那么有一堆很棒的辅助函数可用于各种用例,包括BooleansStrings. 我建议你仔细阅读各种 Apache 库,看看它们已经提供了什么。

于 2014-05-09T01:51:14.917 回答
25

或者借助 Java 8 Optional 的强大功能,您也可以这样做:

Optional.ofNullable(boolValue).orElse(false)

:)

于 2019-07-30T22:35:22.690 回答
16

Boolean类型可以null。您需要进行null检查,因为您已将其设置为null.

if (bool != null && bool)
{
  //DoSomething
}                   
于 2012-06-12T21:42:28.777 回答
5

Boolean 是原始布尔值的对象包装类。这个类,与任何类一样,确实可以为空。出于性能和内存原因,最好始终使用原语。

Java API 中的包装类有两个主要用途:

  1. 提供一种在对象中“包装”原始值的机制,以便可以将原始值包含在为对象保留的活动中,例如添加到集合中,或从具有对象返回值的方法返回。
  2. 为原语提供各种实用功能。这些函数中的大多数都与各种转换有关:将基元与字符串对象相互转换,以及将基元和字符串对象与不同的基数(或基数)相互转换,例如二进制、八进制和十六进制。

http://en.wikipedia.org/wiki/Primitive_wrapper_class

于 2012-06-12T22:14:34.147 回答
1

由于您的变量 bool 指向空值,因此您将始终得到 NullPointerException,您需要先在某个地方使用非空值初始化变量,然后再对其进行修改。

于 2012-06-12T21:48:37.813 回答
1

if (bool)将被编译为if (bool.booleanValue())并且会抛出一个NPEif boolis null

可空盒装布尔评估的其他解决方案:

  • JDK 9+

    import static java.util.Objects.requireNonNullElse;
    
    if (requireNonNullElse(bool, false)) {
        // DoSomething
    
  • 谷歌番石榴 18+

    import static com.google.common.base.MoreObjects.firstNonNull;
    
    if (firstNonNull(bool, false)) {
        // DoSomething
    

false此处用于空情况。

于 2021-07-20T07:11:59.057 回答
0

对象.equals()

K-ballo 接受的答案没有任何问题。如果您喜欢一个简单的条件并且像我一样不喜欢 Yoda 条件,那么从 java 1.7 开始,答案是

    if (Objects.equals(bool, true)) {

或者如果同时你更喜欢非常明确

    if (Objects.equals(bool, Boolean.TRUE)) {

或者更好:避免这个问题

不建议使用Boolean对象,从而首先允许Boolean引用null。像你看到的那样的风险NullPointerException太大了。如果您需要一种三态逻辑,最好定义一个具有三个值的枚举。例如

enum MyTristateBoolean { FALSE, DONT_KNOW, TRUE }

现在我们根本不需要null。中间常数可能应该命名为UNKNOWN,或其他名称UNDEFINEDNOT_EXISTING具体取决于您的具体情况。NULL如果合适的话,你甚至可以命名它。现在根据口味,您的比较成为以下两者之一。

    if (myBool.equals(MyTristateBoolean.TRUE)) {

    if (myBool == MyTristateBoolean.TRUE) {

后者有效,因为编译器保证每个枚举常量只有一个实例。正如你们大多数人所知==,对于比较非枚举类型的对象是否相等是无效的。

于 2021-12-06T18:50:54.693 回答