1. 概述

本文快速梳理 Java 8 中最值得关注的新特性,重点探讨接口默认方法与静态方法、方法引用以及 Optional 容器类。此前我们已单独深入解析过 Stream APILambda 表达式与函数式接口,本文聚焦其他核心改进。

2. 接口默认方法与静态方法

Java 8 前,接口只能包含公共抽象方法。向现有接口添加新功能会强制所有实现类重写,也无法在接口中定义方法实现。Java 8 打破此限制,允许接口包含 静态方法默认方法,二者均可拥有具体实现。

2.1 静态方法

Vehicle 接口为例:

static String producer() {
    return "N&F Vehicles";
}

静态方法仅能通过接口名调用,实现类无法重写:

String producer = Vehicle.producer();

2.2 默认方法

通过 default 关键字声明,可通过实例调用且允许重写。在 Vehicle 接口中添加默认方法:

default String getOverview() {
    return "ATV made by " + producer();
}

假设 VehicleImpl 实现该接口,调用方式如下:

Vehicle vehicle = new VehicleImpl();
String overview = vehicle.getOverview();

3. 方法引用

方法引用是 Lambda 表达式的简化替代方案,专用于调用现有方法。分为四种类型:

3.1 静态方法引用

语法:ContainingClass::methodName
统计空字符串示例:

// Lambda 写法
boolean isReal = list.stream().anyMatch(u -> User.isRealUser(u));

// 方法引用写法
boolean isReal = list.stream().anyMatch(User::isRealUser);

3.2 实例方法引用

语法:containingInstance::methodName
调用实例方法验证输入:

User user = new User();
boolean isLegalName = list.stream().anyMatch(user::isLegalName);

3.3 特定类型实例方法引用

语法:ContainingType::methodName
统计空字符串的简洁写法:

long count = list.stream().filter(String::isEmpty).count();

3.4 构造器引用

语法:ClassName::new
将元素映射为 User 实例:

Stream<User> stream = list.stream().map(User::new);

4. Optional

Java 8 前,开发者需频繁进行 null 检查以避免 NullPointerException,代码冗长易错。Optional<T> 作为容器类,优雅处理可能为 null 的值。

4.1 创建 Optional

三种创建方式:

// 创建空 Optional
Optional<String> optional = Optional.empty();

// 包装非 null 值
String str = "value";
Optional<String> optional = Optional.of(str);

// 包装可能为 null 的值
Optional<String> optional = Optional.ofNullable(getString());

4.2 Optional 使用场景

替代三元运算符

传统写法:

List<String> list = getList();
List<String> listOpt = list != null ? list : new ArrayList<>();

Optional 写法:

List<String> listOpt = getList().orElseGet(() -> new ArrayList<>());

避免嵌套 null 检查

传统多层判断:

User user = getUser();
if (user != null) {
    Address address = user.getAddress();
    if (address != null) {
        String street = address.getStreet();
        if (street != null) {
            return street;
        }
    }
}
return "not specified";

Optional 链式调用:

Optional<User> user = Optional.ofNullable(getUser());
String result = user
  .map(User::getAddress)
  .map(Address::getStreet)
  .orElse("not specified");

注意:若 getter 返回 Optional<T>,需改用 flatMap()

Optional<OptionalUser> optionalUser = Optional.ofNullable(getOptionalUser());
String result = optionalUser
  .flatMap(OptionalUser::getAddress)
  .flatMap(OptionalAddress::getStreet)
  .orElse("not specified");

替换异常类型

传统 try-catch:

String value = null;
String result = "";
try {
    result = value.toUpperCase();
} catch (NullPointerException exception) {
    throw new CustomException();
}

Optional 写法:

String value = null;
Optional<String> valueOpt = Optional.ofNullable(value);
String result = valueOpt.orElseThrow(CustomException::new).toUpperCase();

设计提示Optional 的使用场景存在争议,需根据项目实际权衡。深入探讨可参考 Joda-Time 作者的解析

5. 总结

本文梳理了 Java 8 的核心新特性,包括接口方法扩展、方法引用和 Optional 容器类。这些改进显著提升了代码的简洁性和健壮性。完整示例代码可在 GitHub 获取,建议结合实践深入探索。


原始标题:New Features in Java 8

» 下一篇: Java Stream 介绍