JDK8新特性详解
文章目录
- 1. Lambda 表达式(Lambda Expressions)
- 2. Stream API
- 3. 默认方法(Default Methods)
- 4. 方法引用(Method References)
- 5. Optional 类
- 6. 新的日期和时间 API(java.time)
- 7. Nashorn JavaScript 引擎
- 8. 重复注解(Repeating Annotations)
Java 8(JDK 8)引入了许多重要的新特性,极大地增强了语言的功能和灵活性。以下是一些关键的新特性:
1. Lambda 表达式(Lambda Expressions)
Lambda 表达式是 Java 8 引入的一个重要特性,它允许你以更简洁的方式实现匿名函数(即没有名字的函数)。它可以帮助你写出更加简洁和灵活的代码,特别是在操作集合时。
语法:
(parameters) -> expression
- 参数:可以是一个或多个参数。
- 箭头符号:-> 表示 Lambda 表达式的开始。
- 表达式:可以是一个单一的语句或一个代码块。
示例:
// 不带参数的Lambda
Runnable r = () -> System.out.println("Hello, world!");
r.run(); // 输出: Hello, world!
// 带参数的Lambda
List<String> list = Arrays.asList("a", "b", "c");
list.forEach(s -> System.out.println(s)); // 输出: a, b, c
Lambda 表达式使得代码更加简洁,特别是与函数式接口(仅有一个抽象方法的接口)配合使用时。
常用于事件处理、集合操作、并行处理等场景。
2. Stream API
Stream API 提供了一种更加声明式的方式来处理集合数据。它支持多种操作(如过滤、映射、排序等),并且可以通过 Lambda 表达式和方法引用进一步简化代码。
示例:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 使用 Stream 进行操作
List<Integer> squares = numbers.stream()
.map(x -> x * x) // 映射每个元素为其平方
.collect(Collectors.toList()); // 收集为列表
System.out.println(squares); // 输出: [1, 4, 9, 16, 25]
常见操作:
filter
:过滤元素map
:映射转换reduce
:归约操作(如求和、求最小值等)collect
:将 Stream 转换为集合
- Stream 不会修改原始数据结构,而是生成一个新的结果。
- 可以通过链式调用多个操作。
- 可以支持并行流(parallel stream),提高性能。
3. 默认方法(Default Methods)
Java 8 引入了默认方法,允许在接口中提供方法的默认实现。这样,接口可以有方法实现,而不必影响已经实现该接口的类。
示例:
interface MyInterface {
default void defaultMethod() {
System.out.println("This is a default method.");
}
}
class MyClass implements MyInterface {
// 无需实现 defaultMethod
}
MyClass obj = new MyClass();
obj.defaultMethod(); // 输出: This is a default method.
- 默认方法可以让接口有方法体,不需要所有实现类都去重写。
- 可以通过
default
关键字在接口中定义。- 可与抽象方法和静态方法一起使用。
4. 方法引用(Method References)
方法引用是 Lambda 表达式的简化形式,通过引用现有的方法来简化代码,增加代码的可读性。
语法:
ClassName::methodName
示例:
// 使用 Lambda 表达式
List<String> list = Arrays.asList("a", "b", "c");
list.forEach(s -> System.out.println(s)); // 使用 Lambda
// 使用方法引用
list.forEach(System.out::println); // 方法引用,效果相同
常见类型:
- 静态方法引用:
ClassName::staticMethod
- 实例方法引用:
instance::instanceMethod
- 构造方法引用:
ClassName::new
5. Optional 类
Optional
是一个容器类,用于避免出现 NullPointerException
。它可以包含或不包含一个非空值,提供了很多安全操作方法。
示例:
Optional<String> name = Optional.of("John");
name.ifPresent(System.out::println); // 输出: John
Optional<String> emptyName = Optional.empty();
emptyName.ifPresent(System.out::println); // 什么也不输出
常见方法:
- of():创建一个包含非空值的 Optional。
- empty():创建一个空的 Optional。
- isPresent():判断 Optional 是否包含值。
- orElse():如果 Optional 为空,返回一个默认值。
关键点:
- Optional 可以防止显式地进行 null 值检查。
- 常用于返回值可能为空的方法。
6. 新的日期和时间 API(java.time)
Java 8 引入了新的日期时间 API,解决了老版本中 java.util.Date
和 java.util.Calendar
的一些缺陷,提供了更直观、更易用的方式来处理日期和时间。
示例:
LocalDate date = LocalDate.now(); // 获取当前日期
LocalTime time = LocalTime.now(); // 获取当前时间
LocalDateTime dateTime = LocalDateTime.now(); // 获取当前日期和时间
// 日期加减
LocalDate tomorrow = date.plusDays(1); // 明天
LocalDate yesterday = date.minusDays(1); // 昨天
System.out.println(date); // 输出: 2025-01-13
常见类:
- LocalDate:表示不含时间的日期(年、月、日)。
- LocalTime:表示不含日期的时间(小时、分钟、秒)。
- LocalDateTime:表示同时含有日期和时间的对象。
- ZonedDateTime:带有时区信息的日期时间。
关键点:
- 新的日期时间 API 是不可变的,线程安全。
- 更易于进行时间操作(如加减、格式化等)。
7. Nashorn JavaScript 引擎
Nashorn 是 Java 8 引入的新的 JavaScript 引擎,可以直接在 Java 中执行 JavaScript 代码,替代了之前的 Rhino 引擎。
示例:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval("print('Hello, Nashorn!')");
- 通过 Nashorn,可以将 Java 和 JavaScript 混合编程,灵活处理一些脚本需求。
- 提供了较好的性能和 JavaScript 支持。
8. 重复注解(Repeating Annotations)
Java 8 允许在同一个元素上使用相同的注解多次,这通过 @Repeatable
注解来实现。
示例:
@Repeatable(Schedules.class)
@interface Schedule {
String day();
String time();
}
@interface Schedules {
Schedule[] value();
}
// 使用多个相同的注解
@Schedule(day = "Monday", time = "10:00")
@Schedule(day = "Tuesday", time = "11:00")
class Test { }
Java 8 带来了很多重要的新特性,使得开发者能够以更简洁、更现代的方式进行编程。特别是 Lambda 表达式、Stream API 和新的日期时间 API,在性能、可读性和开发效率上都有显著提升。