Java 8 是 Java 发展史上一个重要的版本,引入了许多革命性的新特性,极大地提升了开发效率和代码质量。以下是 Java 8 的十大核心新特性及其详细解析:
1. Lambda 表达式
简介
Lambda 表达式是 Java 8 最显著的特性之一,允许将函数作为参数传递或返回函数。它简化了匿名内部类的写法,使代码更简洁、更灵活。
语法
(parameters) -> expression
// 或
(parameters) -> { statements; }
示例
// 传统方式(Java 7)
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});
// Lambda 表达式(Java 8)
Collections.sort(names, (a, b) -> b.compareTo(a));
应用场景
- 替代匿名内部类(如线程、事件监听器)
- 集合操作(如排序、过滤)
- 函数式编程中的函数传递
2. Stream API
简介
Stream API 是 Java 8 引入的全新集合处理方式,支持声明式的数据处理操作(过滤、映射、排序、聚合等),并可轻松实现并行处理。
核心概念
- 中间操作:返回 Stream,允许链式调用(如
filter
、map
) - 终端操作:返回特定结果(如
forEach
、collect
)
示例
List<String> filtered = strings.stream()
.filter(s -> !s.isEmpty())
.map(String::toUpperCase)
.sorted()
.collect(Collectors.toList());
优势
- 简化集合操作逻辑
- 支持并行处理(
parallelStream()
) - 提高代码可读性和可维护性
3. 接口默认方法
简介
Java 8 允许在接口中定义默认方法(default
方法),解决了接口升级时破坏现有实现的问题,同时扩展了接口的功能。
语法
public interface MyInterface {
void abstractMethod(); // 抽象方法
default void defaultMethod() {
System.out.println("Default method");
}
}
示例
interface Formula {
double calculate(int a);
default double sqrt(int a) {
return Math.sqrt(a);
}
}
class FormulaImpl implements Formula {
public double calculate(int a) {
return sqrt(a * 100);
}
}
应用场景
- 向后兼容接口升级
- 为接口添加通用工具方法
4. Optional 类
简介
Optional
是一个容器类,用于避免 NullPointerException
。它通过封装可能为 null
的对象,提供安全的访问和操作方法。
核心方法
Optional.of(T value)
:创建非空对象的 Optional。Optional.ofNullable(T value)
:创建可能为null
的对象的 Optional。isPresent()
:判断值是否存在。get()
:获取值(需确保存在)。orElse(T other)
:值不存在时返回默认值。
示例
Optional<String> optional = Optional.of("bam");
optional.ifPresent(System.out::println); // 输出 "bam"
String result = Optional.ofNullable(user).map(User::getName).orElse("Unknown");
优势
- 明确处理空值,避免空指针异常
- 提高代码的健壮性
5. 新的日期时间 API
简介
Java 8 彻底重构了旧的日期时间 API(如 Date
、Calendar
),引入了 java.time
包,提供了更直观、线程安全的日期时间处理方式。
核心类
LocalDate
:仅包含日期(年-月-日)LocalTime
:仅包含时间(时-分-秒)LocalDateTime
:包含日期和时间ZonedDateTime
:带时区的日期时间
示例
LocalDate today = LocalDate.now();
LocalDate nextWeek = today.plusWeeks(1);
LocalDateTime now = LocalDateTime.now();
ZonedDateTime zoned = ZonedDateTime.now(ZoneId.of("America/New_York"));
优势
- 不可变设计,线程安全
- 清晰的时间概念划分(如时区处理)
6. 函数式接口
简介
函数式接口是仅包含一个抽象方法的接口。Java 8 引入了 @FunctionalInterface
注解,明确标识函数式接口。
内置函数式接口
Predicate<T>
:断言型(输入 T,返回 boolean)Function<T, R>
:函数型(输入 T,返回 R)Consumer<T>
:消费型(输入 T,无返回)Supplier<T>
:供给型(无输入,返回 T)
示例
@FunctionalInterface
interface Converter<F, T> {
T convert(F from);
}
Converter<String, Integer> converter = Integer::valueOf;
Integer converted = converter.convert("123");
7. 方法引用
简介
方法引用是 Lambda 表达式的简化形式,直接引用已有的方法或构造函数。
类型
- 静态方法引用:
ClassName::staticMethod
- 实例方法引用:
instance::method
- 类构造函数引用:
ClassName::new
示例
List<String> names = Arrays.asList("Alice", "Bob");
names.forEach(System.out::println); // 引用静态方法
List<Integer> numbers = Arrays.asList(1, 2, 3);
numbers.stream().map(String::valueOf).forEach(System.out::print); // 引用实例方法
8. 重复注解
简介
Java 8 允许在同一个位置使用多个相同类型的注解,通过 @Repeatable
注解实现。
示例
@Repeatable(Permissions.class)
@interface Permission {
String value();
}
@Permission("read")
@Permission("write")
class MyClass {}
应用场景
- 框架开发中,对同一元素标记多个注解
9. 参数名称发现
简介
Java 8 引入了参数名称发现功能,允许在运行时获取方法参数的名称(需启用 -parameters
编译选项)。
示例
public class Example {
public void method(@Param String name) {
// ...
}
}
// 使用反射获取参数名称
Method method = Example.class.getMethod("method", String.class);
Parameter[] parameters = method.getParameters();
for (Parameter param : parameters) {
System.out.println(param.getName()); // 输出 "name"
}
10. 新的 JSR 规范
简介
Java 8 引入了多个新的 JSR(Java Specification Requests)规范,例如:
- JSR 310:新的日期和时间 API
- JSR 335:Lambda 表达式的实现
其他改进
- Nashorn JavaScript 引擎:在 JVM 上运行 JavaScript
- JVM 内部优化:如移除永久代(PermGen),引入元空间(Metaspace)
总结
Java 8 的十大新特性从语言层面到 API 设计都带来了革命性的变化,显著提升了开发效率和代码质量。掌握这些特性不仅能帮助开发者编写更简洁、高效的代码,还能适应现代 Java 开发的需求。建议通过实际项目逐步应用这些特性,例如从集合处理场景开始使用 Stream API,逐步重构传统代码为 Lambda 表达式,并在新项目中全面采用新的日期时间 API。