一、前言
在Java编程中,空指针异常(NullPointerException, NPE)是最常见的问题之一。为了解决这一问题,Java 8 引入了 Optional 类,这是一种容器类,可以用来表示一个值存在或不存在。Optional 是一个容器对象,它可以包含一个非空的值,也可以表示值的缺失(空)。它的主要目的是减少代码中的显式 null 检查,并提供更加优雅的处理方式
二、代码实践
1.创建Optional对象
1.1 使用 Optional.of():
package com.example.springbootdemo.test;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<String> optional = Optional.of("hello");
System.out.println(optional.get());
Optional<Object> nullOptional = Optional.of(null);
}
}
运行结果:

Optional.of() 用于创建一个非空的 Optional 对象。如果传入的值为 null,它会抛出 NullPointerException。
1.2 使用 Optional.ofNullable():
package com.example.springbootdemo.test;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<String> optional = Optional.of("hello");
System.out.println(optional.get());
Optional<Object> nullOptional = Optional.ofNullable(null);
}
}
运行结果:

Optional.ofNullable() 用于创建一个可能为空的 Optional 对象。如果传入的值为 null,它会返回一个空的 Optional。
1.3 使用 Optional.empty():
package com.example.springbootdemo.test;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<Object> empty = Optional.empty();
System.out.println(empty.isPresent());
}
}
Optional.empty() 用于创建一个空的 Optional 对象。
2.检查Optional的值
2.1 使用 isPresent()
isPresent() 方法用于检查 Optional 是否包含值。如果包含值,返回 true;否则返回 false。
package com.example.springbootdemo.test;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<Object> helloOptional = Optional.of("hello");
System.out.println(helloOptional.isPresent());
Optional<Object> emptyOptional = Optional.empty();
System.out.println(emptyOptional.isPresent());
}
}
运行结果:

2.2 使用 ifPresent()
ifPresent() 方法接受一个 Consumer,如果 Optional 中存在值,就执行该 Consumer 的操作。
package com.example.springbootdemo.test;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<Object> helloOptional = Optional.of("hello");
helloOptional.ifPresent(s -> System.out.println(s));
}
}
运行结果:

2.3 使用 orElse()
orElse() 方法用于在 Optional 为空时返回一个默认值。
package com.example.springbootdemo.test;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Object defaultValue = Optional.ofNullable(null).orElse("default value");
System.out.println(defaultValue);
}
}
运行结果:

2.4 使用 orElseGet()
orElseGet() 与 orElse() 类似,但它接受一个 Supplier 接口,用于延迟计算默认值。
package com.example.springbootdemo.test;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Object defaultValue = Optional.ofNullable(null).orElseGet(() -> "Computed default value");
System.out.println(defaultValue);
}
}
运行结果:

2.5 使用 orElseThrow()
orElseThrow() 方法在 Optional 为空时抛出一个异常。
package com.example.springbootdemo.test;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional.ofNullable(null).orElseThrow(() -> new RuntimeException("value is missing"));
}
}
运行结果:

3.操作Optional的值
3.1 使用map()
map() 方法用于对 Optional 中的值进行转换。它接受一个 Function,将 Optional 中的值转换为另一个值,并返回一个新的 Optional。
package com.example.springbootdemo.test;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
//获取长度
Optional<Integer> optional = Optional.of("hello").map(String::length);
System.out.println(optional.get());
}
}
运行结果:

3.2 使用flatMap()
flatMap() 方法与 map() 类似,但用于返回 Optional 的场景。如果转换函数返回的是一个 Optional 对象,那么 flatMap() 会直接返回这个 Optional,而不是嵌套一个 Optional。
package com.example.springbootdemo.test;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<String> optional = Optional.of("hello").flatMap(s -> Optional.of(s.toUpperCase()));
System.out.println(optional.get());
}
}
运行结果:

3.3 使用filter()
filter() 方法用于对 Optional 中的值进行过滤。它接受一个 Predicate,只有在 Predicate 返回 true 时,Optional 中的值才会保留,否则会返回一个空的 Optional。
package com.example.springbootdemo.test;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<String> optional1 = Optional.of("hello world").filter(s->s.length()>5);
System.out.println(optional1.get());
Optional<String> optional = Optional.of("hello").filter(s->s.length()>5);
System.out.println(optional.get());
}
}
运行结果:

三、Optional最佳实践
3.1 避免使用 Optional 作为方法参数
Optional 最好不要作为方法的参数使用,因为这样可能导致不必要的复杂性。相反,可以直接传递实际的对象值,并在方法内部处理 null 值。
3.2 使用 Optional 代替返回 null
Optional 主要用于替代返回 null 的情况。当一个方法可能返回一个空值时,使用 Optional 可以让调用者明确地知道可能会有空值。
3.3 避免滥用 Optional
虽然 Optional 是一个很好的工具,但也要避免滥用它。例如,不要在实体类的字段中使用 Optional,因为这会导致序列化和反序列化的问题。
四、总结
Optional 提供了一种优雅的方式来处理可能为空的值,通过减少显式的 null 检查,使代码更加简洁和易读。在使用 Optional 时,遵循最佳实践,可以有效地减少空指针异常的发生。








