Optional类用于优雅表达可能为空的值,减少空指针异常。1. 使用of、ofNullable和empty创建实例;2. 通过ifPresent、orElse系列安全获取值;3. 利用map、flatMap和filter实现链式操作;4.推荐作为方法返回类型,避免作参数或字段;5. 结合Stream提升函数式编程体验,使代码更清晰安全。
在Java 8引入的Optional类,旨在减少空指针异常(NullPointerException)的发生,同时支持函数式编程风格。它不是一个集合,也不是为了完全替代null,而是作为一种更优雅的方式表达“可能不存在的值”。合理使用Optional能让代码更清晰、安全,并与Stream等函数式特性良好结合。
根据值是否存在,可以选择不同的方式创建Optional实例:
String name = "Alice"; OptionaloptName = Optional.of(name); // 包含"Alice" String nullName = null; Optional optNull = Optional.ofNullable(nullName); // 空Optional Optional emptyOpt = Optional.empty(); // 明确为空
直接获取Optional中的值需要避免调用get()前未判断是否为空,否则可能引发异常。推荐使用函数式方法进行安全操作。
OptionaluserName = findUserNameById(123); // 安全输出 userName.ifPresent(name -> System.out.println("Hello, " + name)); // 提供默认值 String displayName = userName.orElse("Guest"); // 延迟计算默认值 String computedName = userName.orElseGet(() -> fetchFromBackup()); // 抛出异常 String realName = userName.orElseThrow(() -> new IllegalArgumentException("User not found"));
Optional支持类似Stream的操作,可以对内部值进行转换或条件判断,提升函数式表达能力。
OptionaluserOpt = getUserById(100); // 获取用户邮箱并转大写 Optional emailOpt = userOpt.map(User::getEmail) .map(String::toUpperCase); // 链式过滤:只保留激活状态用户的邮箱 Optional activeEmail = userOpt.filter(User::isActive) .map(User::getEmail); // flatMap避免Optional > Optional > nested = userOpt.map(u -> getPhoneNumber(u.getId())); // 不推荐 Optional phoneOpt = userOpt.flatMap(u -> getPhoneNumber(u.getId())); // 推荐
Optional最适合用于方法返回值,表明结果可能不存在,而不是作为参数或字段类型。