java 核心技术-12版 卷Ⅰ- 4.3.6 使用null 引用
在4.2.1 节中,我们已经了解到,对象变量包含一个对象的引用,或者包含一个特殊值null ,后者表示没有引用任何对象。
听上去这是一种处理特殊情况的便捷机制,如未知的名字或雇佣日期。不过使用null 值时要非常小心。
如果对null 值应用一个方法,会产生一个 NullPointerException 异常。
这是一个很严重的错误,类似于“索引越界”异常。如果你的程序没有“捕获”异常,那么程序就会终止。正常情况下,程序并不捕获这些异常,而是依赖于程序员从一开始就不要带来异常。
提示: 程序因 NullPointerException 异常终止时,栈轨迹会显示问题出现在哪一行代码中。从Java 17 开始,错误消息会包含有 null值的变量或方法名。例如,在以下调用中:
String e = e.getHireDay().toString();
错误消息会告诉你e 是否为null 或 e.getHireDay是否返回null。
定义一个类时,最好清楚地知道哪些字段可能为null。在我们的例子中,我们不希望 name 或 hireDay 字段为null。(不用担心 salary,它是基本类型,不可能为null)
hireDay 字段肯定是非null的,因为它初始化为一个新的 LocalDate对象。但是,name 可能为null,如果调用构造器时为 n 提供的实参是 null,name就会是 null。
对此有两种解决方法。“宽容”方法是把null参数转换为一个适当的非 null :
Objects 提供了一个便利方法
"严格"方法则干脆拒绝 null 参数
name = Objects.requireNonNullElse(n , "unknown");
如果用null 名字构造一个 Employee 对象,就会产生NullPointerException 异常。乍看上去这种补救方法好像不太有用,不过这种方法有两个好处:
1. 异常报告会提供这个问题的描述
2.异常报告会准确地指出问题所在的位置,否则 NullPointerException异常会出现在其他地方,而很难追踪到真正导致问题的构造器参数。
注释:如果要接受一个对象引用作为构造参数,就要问问自己:是不是真的希望接受可有可无的值。如果不是,那么“严格”方法更合适。