Java程序员真的是烦透了 NullPointerException(NPE),尽管和它熟得就像一位老朋友,知道它也是迫不得已——程序正在使用一个对象却发现这个对象的值为 null,于是 Java 虚拟机就怒发冲冠地把它抛了出来当作替罪羊。
严格意义上来说,线上环境运行对于NPE是0容忍的。
Java中的Optional是Java 8引入的一个新特性,它可以用来解决空指针异常(NullPointerException)的问题。在Java 8之前,当我们访问一个对象的属性或者调用对象的方法时,如果对象为null,就会抛出空指针异常。而使用Optional则可以避免空指针异常的发生,使得代码更加健壮。
Optional是什么?
Optional是一个容器类,它可以包含一个非空值或者为空。通过调用of()方法创建一个Optional对象并初始化这个对象的值,如果初始化的值为null,则会抛出NullPointerException异常。例如:
String str = "hello";
Optional<String> optionalStr = Optional.of(str);
以上代码创建了一个字符串类型的Optional对象并设置了初始值为"hello"。
如果我们不确定要初始化的值是否为null,可以使用ofNullable()方法来创建Optional对象。例如:
String str = null;
Optional<String> optionalStr = Optional.ofNullable(str);
上述代码创建了一个字符串类型的Optional对象并设置了初始值为null。如果我们想要创建一个空的Optional对象,可以使用empty()方法。例如:Optional<String> optionalStr = Optional.empty();
Optional如何获取值?
我们可以使用get()方法来获取Optional对象中的值,如果Optional对象中的值为null,则会抛出NoSuchElementException异常。例如:
String str = "hello";
Optional<String> optionalStr = Optional.of(str);
String result = optionalStr.get();
System.out.println(result);
以上代码会输出"hello"。
由于get()方法可能会抛出异常,因此我们可以先使用isPresent()方法判断Optional对象中是否有值。例如:
String str = "hello";
Optional<String> optionalStr = Optional.of(str);
if (optionalStr.isPresent()) {
String result = optionalStr.get();
System.out.println(result);
}
以上代码也会输出"hello"。
我们还可以使用orElse()方法获取Optional对象中的值,如果Optional对象中的值为null,则返回传入的默认值。例如:
String str = null;
Optional<String> optionalStr = Optional.ofNullable(str);
String result = optionalStr.orElse("world");
System.out.println(result);
以上代码会输出"world",因为初始化的值为null。
Optional的其他操作
除了上述方法之外,Optional还提供了一些其他的操作,如map()、flatMap()、filter()等。这些操作可以使得我们更加方便地处理Optional对象。例如:
String str = "hello";
Optional<String> optionalStr = Optional.of(str);
Optional<Integer> optionalLength = optionalStr.map(String::length);
int length = optionalLength.orElse(0);
System.out.println(length);
以上代码会输出"5",因为字符串"hello"的长度为5。在这个例子中,我们使用了map()方法将字符串类型的Optional对象转化为整数类型的Optional对象,然后使用orElse()方法获取Optional对象中的值。
flatMap是Optional类中的一种方法,它的作用是将一个Optional对象中的值进行转换,并返回一个新的Optional对象。这个方法通常用于处理嵌套的Optional对象。
当你想要访问一个可能为空的对象时,可以使用Optional来包装它,然后使用flatMap来获取它的值。如果对象为空,则不执行任何操作,而是返回一个空的Optional对象。
下面是一个简单的例子,展示了如何使用Optional和flatMap:
Optional<String> name = Optional.of("John");
Optional<Integer> length = name.flatMap(str -> Optional.of(str.length()));
在上面的代码中,我们创建了一个包装了字符串"John"的Optional对象。然后,我们使用flatMap将这个字符串的长度包装成一个新的Optional对象。如果name对象为空,那么length对象也会为空。
Java Optional的妙用
Java Optional是一个非常实用的类,它可以帮助我们更好地处理可能为空的值。以下是Java Optional的一些妙用:
1. 属性访问
使用Optional可以安全地访问对象的属性,即使对象本身是null。
例如,下面的代码演示了如何使用Optional来访问一个对象的属性:
Optional<User> optionalUser = Optional.ofNullable(getCurrentUser());
String username = optionalUser.map(User::getUsername).orElse("guest");
在上面的代码中,如果当前用户不为空,则获取当前用户的用户名。否则使用默认值"guest"。
2. 缩短代码
使用Optional可以减少代码量,并使代码更加清晰易懂。例如,下面的代码演示了如何使用Optional来缩短代码:
// 传统写法
String result = null;
if (value != null && value.length() > 0) {
result = value.toUpperCase();
} else {
result = "default";
}
// 使用Optional的写法
String result = Optional.ofNullable(value)
.filter(v -> v.length() > 0)
.map(String::toUpperCase)
.orElse("default");
在上面的代码中,我们使用Optional来避免了冗长的if-else语句,并且使代码更加清晰易懂。
3. 链式方法
使用Optional可以方便地链式调用多个方法,而不必担心null值的问题。例如,下面的代码演示了如何使用Optional进行链式方法调用:
Optional.ofNullable(getUser())
.flatMap(user -> user.getOrder())
.flatMap(order -> order.getItems())
.map(items -> items.stream().mapToDouble(Item::getPrice).sum())
.orElse(0.0);
在上面的代码中,我们通过使用flatMap()和map()方法来链式调用多个方法,从而避免了null值的问题。如果getUser()返回null,则整个表达式将返回默认值0.0。
- END -
下方扫码关注 软件质量保障,与质量君一起学习成长、共同进步,做一个职场最贵Tester!
后台回复【测开】获取测试开发xmind脑图
后台回复【加群】获取加入测试社群方式,领2T测试自学视频
往期推荐