1. 概述
本文快速梳理 Java 8 中最值得关注的新特性,重点探讨接口默认方法与静态方法、方法引用以及 Optional 容器类。此前我们已单独深入解析过 Stream API 和 Lambda 表达式与函数式接口,本文聚焦其他核心改进。
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 获取,建议结合实践深入探索。