如果你使用内置的 null
来表示没有对象,每次使用引用的时候就必须测试一下引用是否为 null
,这显得有点枯燥,而且势必会产生相当乏味的代码。问题在于 null
没什么自己的行为,只会在你想用它执行任何操作的时候产生 NullPointException
。java.util.Optional
(首次出现是在函数式编程这章)为 null
值提供了一个轻量级代理,Optional
对象可以防止你的代码直接抛出 NullPointException
。
举个简单的例子,很多系统中都有 Person 类型,代码中有些情况下你可能没有一个实际的 Person 对象(或者可能有,但是你还没用关于那个人的所有信息)。这时,在传统方法下,你会用到一个 null 引用,并且在使用的时候测试它是不是 null。而现在,我们可以使用 Optional:
// typeinfo/Person.java
// Using Optional with regular classes
import onjava.*;
import java.util.*;
class Person {
public final Optional<String> first;
public final Optional<String> last;
public final Optional<String> address;
// etc.
public final Boolean empty;
Person(String first, String last, String address) {
this.first = Optional.ofNullable(first);
this.last = Optional.ofNullable(last);
this.address = Optional.ofNullable(address);
empty = !this.first.isPresent()
&& !this.last.isPresent()
&& !this.address.isPresent();
}
Person(String first, String last) {
this(first, last, null);
}
Person(String last) {
this(null, last, null);
}
Person() {
this(null, null, null);
}
@Override
public String toString() {
if (empty)
return "<Empty>";
return (first.orElse("") +
" " + last.orElse("") +
" " + address.orElse("")).trim();
}
public static void main(String[] args) {
System.out.println(new Person());
System.out.println(new Person("Smith"));
System.out.println(new Person("Bob", "Smith"));
System.out.println(new Person("Bob", "Smith",
"11 Degree Lane, Frostbite Falls, MN"));
}
}