如何在 Java 中检查布尔值是否为 null

JavaBeginner
立即练习

介绍

在这个实验中,你将学习在 Java 中处理 Boolean 对象时如何安全地处理 null 值。我们将探讨与基本数据类型 boolean 相比,在处理 Boolean 包装类时可能出现的 NullPointerException 问题。

你将学习在访问 Boolean 对象的值之前检查其是否为 null 的正确方法,使用 Optional 类进行更健壮的空值处理,并通过实际示例了解基本数据类型 booleanBoolean 包装类在空值处理上的关键区别。

检查布尔对象是否为 null

在这一步中,我们将探讨在 Java 中处理 Boolean 对象时如何处理潜在的 null 值。与基本数据类型 boolean 总是为 truefalse 不同,Boolean 包装类可以持有 null 值。如果处理不当,这通常会导致 NullPointerException 错误。

让我们创建一个简单的 Java 程序来演示这一点。

  1. 打开 WebIDE 编辑器。

  2. 在左侧的文件资源管理器中,确保你位于 ~/project 目录下。

  3. 在文件资源管理器的空白处右键单击,选择“新建文件”,并将其命名为 BooleanCheck.java

  4. 在编辑器中打开 BooleanCheck.java 文件。

  5. 将以下代码复制并粘贴到编辑器中:

    public class BooleanCheck {
        public static void main(String[] args) {
            Boolean myBoolean = null;
    
            // This will cause a NullPointerException if myBoolean is null
            // if (myBoolean) {
            //     System.out.println("myBoolean is true");
            // }
    
            // Correct way to check for null before accessing the boolean value
            if (myBoolean != null && myBoolean) {
                System.out.println("myBoolean is true");
            } else if (myBoolean == null) {
                System.out.println("myBoolean is null");
            } else {
                System.out.println("myBoolean is false");
            }
        }
    }

    在这段代码中:

    • 我们声明了一个 Boolean 对象 myBoolean 并将其初始化为 null
    • 注释掉的 if (myBoolean) 行展示了一个常见的错误,当 myBooleannull 时会导致 NullPointerException
    • if (myBoolean != null && myBoolean) 行展示了在尝试计算其布尔值之前检查 Boolean 对象是否不为 null 的正确方法。&& 运算符是一个短路运算符,这意味着如果 myBoolean != nullfalse,则不会计算第二部分 (myBoolean),从而避免了错误。
  6. 保存文件(Ctrl+S 或 Cmd+S)。

  7. 打开 WebIDE 底部的终端。使用命令 cd ~/project 确保你位于 ~/project 目录下。

  8. 输入以下命令并按回车键来编译 Java 程序:

    javac BooleanCheck.java

    如果没有错误,你将看不到任何输出。~/project 目录下将创建一个 BooleanCheck.class 文件。

  9. 使用以下命令并按回车键来运行编译后的程序:

    java BooleanCheck

    你应该会看到以下输出:

    myBoolean is null

这个输出证实了我们的程序正确识别出 myBooleannull,并避免了 NullPointerException。理解如何处理 Boolean 对象的 null 值对于编写健壮的 Java 代码至关重要。

使用 Optional 类处理 null 值

在这一步中,我们将探索一种更现代的方法,即使用 Java 8 引入的 Optional 类来处理 Java 中潜在的 null 值。Optional 是一个容器对象,它可能包含也可能不包含非 null 值。它提供了一种清晰的方式来表明某个值可能不存在,有助于防止 NullPointerException 错误,并使代码更具可读性。

让我们修改之前的示例,以使用 Optional<Boolean>

  1. 在 WebIDE 编辑器中打开 BooleanCheck.java 文件。

  2. 将文件的全部内容替换为以下新代码:

    import java.util.Optional;
    
    public class BooleanCheck {
        public static void main(String[] args) {
            // Creating an Optional that contains a Boolean value
            Optional<Boolean> optionalBooleanPresent = Optional.of(true);
    
            // Creating an Optional that is empty (represents null)
            Optional<Boolean> optionalBooleanEmpty = Optional.empty();
    
            // Handling the present Optional
            if (optionalBooleanPresent.isPresent()) {
                System.out.println("optionalBooleanPresent has a value: " + optionalBooleanPresent.get());
            } else {
                System.out.println("optionalBooleanPresent is empty");
            }
    
            // Handling the empty Optional
            if (optionalBooleanEmpty.isPresent()) {
                System.out.println("optionalBooleanEmpty has a value: " + optionalBooleanEmpty.get());
            } else {
                System.out.println("optionalBooleanEmpty is empty");
            }
    
            // Using orElse to provide a default value if the Optional is empty
            Boolean valueOrDefault = optionalBooleanEmpty.orElse(false);
            System.out.println("Value from optionalBooleanEmpty orElse(false): " + valueOrDefault);
    
            // Using ifPresent to perform an action only if a value is present
            optionalBooleanPresent.ifPresent(value -> System.out.println("Value is present: " + value));
        }
    }

    在这段更新后的代码中:

    • 我们导入了 java.util.Optional 类。
    • 我们创建了两个 Optional<Boolean> 对象:一个包含值 (Optional.of(true)),另一个为空 (Optional.empty())。
    • 我们使用 isPresent() 来检查 Optional 是否包含值。
    • 我们使用 get()Optional 中获取值。注意: 对空的 Optional 调用 get() 会抛出 NoSuchElementException,因此始终先使用 isPresent() 进行检查,或者使用其他 Optional 方法。
    • 我们演示了 orElse(false),如果 Optional 包含值,则返回该值,否则返回指定的默认值(在这种情况下为 false)。
    • 我们展示了 ifPresent(),它接受一个 lambda 表达式,并且仅当 Optional 中存在值时才执行该表达式。
  3. 保存文件(Ctrl+S 或 Cmd+S)。

  4. 打开 WebIDE 底部的终端。使用命令 cd ~/project 确保你位于 ~/project 目录下。

  5. 输入以下命令并按回车键来编译 Java 程序:

    javac BooleanCheck.java

    如果编译成功,将生成一个新的 BooleanCheck.class 文件。

  6. 使用以下命令并按回车键来运行编译后的程序:

    java BooleanCheck

    你应该会看到以下输出:

    optionalBooleanPresent has a value: true
    optionalBooleanEmpty is empty
    Value from optionalBooleanEmpty orElse(false): false
    Value is present: true

这个输出展示了如何使用 Optional 以比仅使用 null 更明确、更安全的方式处理值的存在或缺失。使用 Optional 可以使你的代码更清晰,并降低出现 NullPointerException 的可能性。

使用基本数据类型与包装类进行测试

在这一步中,我们将着重介绍 Java 的基本数据类型 booleanBoolean 包装类之间的关键区别,特别是它们处理 null 值的能力。理解这一区别是在处理布尔值时避免 NullPointerException 的基础。

  • 基本数据类型 boolean:这是 Java 中的一种基本数据类型。它只能存储两个值之一:truefalse。基本数据类型 boolean 变量 永远 不能为 null
  • Boolean 包装类:这是一个包装基本数据类型 boolean 值的对象。由于它是一个对象,Boolean 变量可以持有对 Boolean 对象的引用(该对象包含 truefalse),也可以持有 null 值。

让我们创建一个简单的程序来演示这种区别。

  1. 打开 WebIDE 编辑器。

  2. 在左侧的文件资源管理器中,确保你位于 ~/project 目录下。

  3. 在文件资源管理器的空白处右键单击,选择“新建文件”,并将其命名为 PrimitiveVsWrapper.java

  4. 在编辑器中打开 PrimitiveVsWrapper.java 文件。

  5. 将以下代码复制并粘贴到编辑器中:

    public class PrimitiveVsWrapper {
        public static void main(String[] args) {
            // Declaring a primitive boolean
            boolean primitiveBoolean = true;
    
            // Declaring a Boolean wrapper object
            Boolean wrapperBoolean = null; // Wrapper can be null
    
            System.out.println("Primitive boolean value: " + primitiveBoolean);
    
            // Checking if the wrapper Boolean is null before printing
            if (wrapperBoolean == null) {
                System.out.println("Wrapper Boolean is null");
            } else {
                System.out.println("Wrapper Boolean value: " + wrapperBoolean);
            }
    
            // Attempting to assign null to a primitive boolean will cause a compile-time error
            // primitiveBoolean = null; // Uncommenting this line will cause an error
        }
    }

    在这段代码中:

    • 我们声明了一个基本数据类型 boolean 并将其初始化为 true
    • 我们声明了一个 Boolean 包装类对象并将其初始化为 null。这对于包装类来说是有效的。
    • 我们打印了基本数据类型 boolean 的值。
    • 我们在尝试打印包装类 Boolean 的值之前检查它是否为 null,这展示了对包装类进行空值检查的必要性。
    • 注释掉的代码行表明你不能将 null 赋值给基本数据类型 boolean。如果你取消注释这一行并尝试编译,将会得到一个编译错误。
  6. 保存文件(Ctrl+S 或 Cmd+S)。

  7. 打开 WebIDE 底部的终端。使用命令 cd ~/project 确保你位于 ~/project 目录下。

  8. 输入以下命令并按回车键来编译 Java 程序:

    javac PrimitiveVsWrapper.java

    如果没有错误,将创建一个 PrimitiveVsWrapper.class 文件。

  9. 使用以下命令并按回车键来运行编译后的程序:

    java PrimitiveVsWrapper

    你应该会看到以下输出:

    Primitive boolean value: true
    Wrapper Boolean is null

这个输出清楚地表明,基本数据类型 boolean 持有一个值(true),而 Boolean 包装类对象可以持有 null。在设计 Java 程序和处理可能缺失的值时,这种区别非常重要。

总结

在本次实验中,我们学习了在 Java 里处理 Boolean 对象时如何应对潜在的 null 值。我们了解到,与基本数据类型 boolean 不同,Boolean 包装类可以为 null,这可能会导致 NullPointerException 错误。我们展示了在访问 Boolean 对象的布尔值之前,结合使用 != null 检查和逻辑与运算符 (&&) 来正确检查该对象是否不为 null 的方法。这样可以确保只有在对象不为 null 时才会对布尔值进行求值,从而避免运行时错误。