Optional<T>
是 Java 8 引入的一个容器类,用于避免 NullPointerException
(NPE),并鼓励更优雅的代码风格。它提供了多种方法来处理可能为空的值。以下是一些深入学习 Optional
的代码示例:
1. 创建 Optional
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
Optional<String> optional1 = Optional.of("Hello, Java!"); // 不能为 null
Optional<String> optional2 = Optional.ofNullable(null); // 可以为 null
Optional<String> optional3 = Optional.empty(); // 空 Optional
System.out.println(optional1);
System.out.println(optional2);
System.out.println(optional3);
}
}
2. 判断 Optional 是否有值
public class OptionalCheck {
public static void main(String[] args) {
Optional<String> optional = Optional.ofNullable("Java Optional");
if (optional.isPresent()) {
System.out.println("Value: " + optional.get());
}
optional.ifPresent(value -> System.out.println("Using ifPresent: " + value));
}
}
推荐使用 ifPresent()
代替 isPresent()
,这样可以避免手动 get()
取值时可能的 NPE。
3. 使用 orElse()
和 orElseGet()
public class OptionalOrElse {
public static void main(String[] args) {
String nullValue = null;
String result1 = Optional.ofNullable(nullValue).orElse("Default Value");
String result2 = Optional.ofNullable(nullValue).orElseGet(() -> "Computed Value");
System.out.println(result1);
System.out.println(result2);
}
}
orElse()
始终会计算默认值,即使Optional
有值。orElseGet()
只有在Optional
为空时才会计算默认值。
4. 使用 orElseThrow()
抛异常
public class OptionalOrElseThrow {
public static void main(String[] args) {
try {
String value = Optional.ofNullable(null)
.orElseThrow(() -> new IllegalArgumentException("Value is missing"));
System.out.println(value);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
如果 Optional
为空,就会抛出指定异常。
5. 使用 map()
处理 Optional
public class OptionalMap {
public static void main(String[] args) {
Optional<String> optional = Optional.of("java optional");
Optional<Integer> lengthOptional = optional.map(String::length);
lengthOptional.ifPresent(length -> System.out.println("Length: " + length));
}
}
map()
用于对 Optional
中的值进行转换。
6. 使用 flatMap()
处理嵌套 Optional
import java.util.Optional;
public class OptionalFlatMap {
public static void main(String[] args) {
Optional<Optional<String>> nestedOptional = Optional.of(Optional.of("Nested Optional"));
Optional<String> flatMapped = nestedOptional.flatMap(opt -> opt);
flatMapped.ifPresent(System.out::println);
}
}
如果 map()
返回的是 Optional
,那么会得到嵌套 Optional<Optional<T>>
,使用 flatMap()
可以去除嵌套。
7. 过滤 Optional 值
public class OptionalFilter {
public static void main(String[] args) {
Optional<String> optional = Optional.of("Hello Java");
optional.filter(value -> value.startsWith("Hello"))
.ifPresent(System.out::println);
optional.filter(value -> value.startsWith("World"))
.ifPresentOrElse(System.out::println,
() -> System.out.println("Filter condition not met"));
}
}
filter()
允许对 Optional
值进行条件筛选。
8. 应用场景:避免 NPE
class User {
private String name;
public User(String name) {
this.name = name;
}
public Optional<String> getName() {
return Optional.ofNullable(name);
}
}
public class OptionalUsage {
public static void main(String[] args) {
User user = new User(null);
String username = user.getName().orElse("Anonymous");
System.out.println(username);
}
}
这里 getName()
返回 Optional<String>
,调用方可以优雅地处理 null
,避免 NullPointerException
。
9. 组合多个 Optional
public class OptionalCombination {
public static void main(String[] args) {
Optional<String> first = Optional.of("First");
Optional<String> second = Optional.empty();
String result = first.or(() -> second).orElse("Default");
System.out.println(result);
}
}
or()
允许你在多个 Optional
之间取第一个有值的。
总结:
-
创建 Optional
Optional.of(value)
: 不能为null
Optional.ofNullable(value)
: 允许null
Optional.empty()
: 创建空Optional
-
判断是否有值
isPresent()
(不推荐)ifPresent(Consumer)
-
获取值
get()
(不推荐)orElse(defaultValue)
orElseGet(Supplier)
orElseThrow(Supplier<Throwable>)
-
转换值
map(Function<T, R>)
flatMap(Function<T, Optional<R>>)
filter(Predicate)
-
组合 Optional
or(Supplier<Optional<T>>)
orElse()
/orElseGet()
这样,你可以在 Java 项目中更优雅地处理 null
,减少 NPE 发生的可能性。🚀