# Java进阶新版本特性
# 1. Java 8 特性详解
# 1.1 函数式编程与 Lambda 表达式
设计思想转变: 传统的面向对象编程就像邮局寄信,必须填写完整的邮寄单(创建对象、实现接口)。Lambda 表达式则像快递扫码,只需"滴"一声就能完成身份验证。
传统匿名内部类写法:
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Hello");
}
};
Lambda 表达式写法:
Runnable r = () -> System.out.println("Hello");
结构对比:
传统:new 接口名() { 方法实现... }
Lambda: (参数) -> { 方法体 }
2
3
4
5
6
7
8
9
10
11
12
13
14
核心概念:
// 1. 无参数,无返回值
Runnable r1 = () -> System.out.println("Hello");
// 2. 一个参数,无返回值
Consumer<String> c = (name) -> System.out.println(name);
// 3. 省略参数括号(只有一个参数时)
Consumer<String> c = name -> System.out.println(name);
// 4. 多个参数,有返回值
Comparator<Integer> comp = (a, b) -> {
System.out.println("比较:" + a + "和" + b);
return a - b;
};
// 5. 方法引用(进一步简化)
List<String> names = Arrays.asList("Tom", "Jerry");
names.forEach(System.out::println); // 静态方法引用
names.forEach(String::toUpperCase); // 实例方法引用
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
应用场景:
// 集合排序
List<String> list = Arrays.asList("banana", "apple", "orange");
list.sort((s1, s2) -> s1.compareTo(s2));
// 线程创建
new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}).start();
// 事件处理
button.addActionListener(e -> System.out.println("按钮被点击"));
2
3
4
5
6
7
8
9
10
11
12
13
# 1.2 Stream API 流式处理
流水线作业思想: 传统集合操作像手工车间,每个工序独立完成。Stream 像自动化流水线,原料(数据)在流水线上依次经过各个工位(操作)。
传统方式处理集合:
原材料:[苹果, 香蕉, 橙子, 西瓜, 葡萄]
步骤:
1. 筛选长度>2的水果 → [苹果, 香蕉, 橙子, 西瓜, 葡萄]
2. 转换为大写 → [苹果, 香蕉, 橙子, 西瓜, 葡萄](中文不变)
3. 排序 → [西瓜, 葡萄, 苹果, 香蕉, 橙子]
4. 收集结果
Stream 处理:
stream()
.filter(f -> f.length() > 2) ← 筛选工位
.map(String::toUpperCase) ← 转换工位
.sorted() ← 排序工位
.collect(toList()) ← 包装工位
2
3
4
5
6
7
8
9
10
11
12
13
14
Stream 操作分类:
Stream操作三阶段:
中间操作(可多个) 终止操作(一个)
数据源 → 筛选/转换/排序... → 筛选/转换/排序... → 收集/统计
中间操作(懒加载):
filter - 过滤不符合条件的元素
map - 转换元素类型或值
sorted - 排序
distinct- 去重
limit - 限制数量
skip - 跳过前N个
终止操作:
forEach - 遍历
collect - 收集为集合
count - 计数
reduce - 归约
anyMatch- 是否存在匹配
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
代码示例:
List<String> fruits = Arrays.asList("apple", "banana", "orange", "watermelon");
// 1. 筛选和收集
List<String> longFruits = fruits.stream()
.filter(f -> f.length() > 5)
.collect(Collectors.toList());
// 结果:[banana, orange, watermelon]
// 2. 映射转换
List<Integer> lengths = fruits.stream()
.map(String::length)
.collect(Collectors.toList());
// 结果:[5, 6, 6, 10]
// 3. 排序
List<String> sorted = fruits.stream()
.sorted()
.collect(Collectors.toList());
// 结果:[apple, banana, orange, watermelon]
// 4. 并行处理提高性能
long count = fruits.parallelStream()
.filter(f -> f.contains("a"))
.count();
// 5. 分组统计
Map<Integer, List<String>> groupByLength = fruits.stream()
.collect(Collectors.groupingBy(String::length));
// 结果:{5=[apple], 6=[banana, orange], 10=[watermelon]}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 1.3 Optional 类深度解析
空指针防护罩设计思想: Optional 就像一个智能包装盒,它明确告诉你:"盒子里可能有东西,也可能没有,但无论如何都不会让你直接摸到空指针。"
传统方式的风险路径:
用户 → 获取地址 → 获取城市 → 获取名称 → NPE!
可能null 可能null 可能null
Optional 的安全路径:
用户 → Optional包装 → 安全获取地址 → 安全获取城市 → 安全获取名称
↓
明确处理空值
2
3
4
5
6
7
8
Optional 使用模式:
// 1. 创建 Optional 对象
Optional<String> empty = Optional.empty(); // 空盒子
Optional<String> value = Optional.of("Hello"); // 非空盒子(值不能为null)
Optional<String> nullable = Optional.ofNullable(null); // 可为空的盒子
// 2. 安全获取值(避免直接get()导致NoSuchElementException)
String result = nullable.orElse("默认值"); // 为空时返回默认值
String result2 = nullable.orElseGet(() -> "生成的值"); // 为空时通过Supplier生成
String result3 = nullable.orElseThrow(() -> new RuntimeException("空值"));
// 3. 安全操作(链式调用)
User user = new User("Tom", 25);
String cityName = Optional.ofNullable(user)
.map(User::getAddress) // 如果user不为空,获取address
.map(Address::getCity) // 如果address不为空,获取city
.map(City::getName) // 如果city不为空,获取name
.orElse("未知城市"); // 任何一步为空,返回默认值
// 4. 条件检查
Optional<String> opt = Optional.of("Hello");
opt.ifPresent(value -> System.out.println("值存在: " + value));
// 5. 过滤
Optional<String> filtered = opt.filter(s -> s.length() > 3);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
应用场景对比:
// 传统写法(危险)
public String getCityName(User user) {
if (user != null) {
Address address = user.getAddress();
if (address != null) {
City city = address.getCity();
if (city != null) {
return city.getName();
}
}
}
return "未知";
}
// Optional 写法(安全简洁)
public String getCityName(User user) {
return Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.map(City::getName)
.orElse("未知");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1.4 默认方法
接口升级兼容性设计: 默认方法就像是给接口这个"合同"增加了可选条款,老客户(已有实现类)可以继续使用原有条款,新客户可以选择使用新条款。
接口演进问题:
旧版本接口: 新需求:添加方法
↓ ↓
实现类A、B、C... 需要全部修改实现类!
默认方法解决方案:
接口 {
旧方法();
default 新方法() { // 提供默认实现
// 默认逻辑
}
}
实现类可以选择:
1. 不覆盖:使用默认实现
2. 覆盖:提供自己的实现
3. 强制覆盖:声明为抽象方法
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
代码示例:
// 1. 基本使用
interface Vehicle {
void start(); // 传统抽象方法
default void honk() { // 默认方法
System.out.println("嘟嘟嘟");
}
static void service() { // 静态方法
System.out.println("车辆维护服务");
}
}
class Car implements Vehicle {
@Override
public void start() {
System.out.println("汽车启动");
}
// 可以不实现 honk(),使用默认实现
}
// 2. 多继承冲突解决
interface A {
default void hello() {
System.out.println("A的hello");
}
}
interface B {
default void hello() {
System.out.println("B的hello");
}
}
class C implements A, B {
@Override // 必须覆盖,解决冲突
public void hello() {
A.super.hello(); // 显式调用A的默认方法
System.out.println("C的hello");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 1.5 新的日期时间 API
设计思想: 旧的 Date 和 Calendar 就像一本混乱的日记,各种时区、格式混在一起。新的日期时间 API 就像精密的瑞士手表,每个组件都职责清晰、不可变、线程安全。
旧API问题:
Date date = new Date();
// date 可变,非线程安全
// 月份从0开始(反人类)
// 没有时区处理
// 格式化与解析混乱
新API结构体系:
TemporalAccessor(时间访问器)
↑
java.time 包核心结构
LocalDate LocalTime LocalDateTime
(日期) (时间) (日期时间)
ZonedDateTime Instant Duration
(带时区) (时间戳) (时间段)
Period DateTimeFormatter
(日期间隔) (格式化)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
核心类使用:
// 1. 创建日期时间对象
LocalDate today = LocalDate.now(); // 2023-10-01
LocalTime now = LocalTime.now(); // 14:30:15.123
LocalDateTime current = LocalDateTime.now(); // 2023-10-01T14:30:15.123
// 2. 指定日期时间
LocalDate birthday = LocalDate.of(1990, Month.MAY, 15);
LocalTime meetingTime = LocalTime.of(14, 30);
LocalDateTime event = LocalDateTime.of(2023, 12, 25, 20, 0);
// 3. 日期计算(不可变对象,每次返回新对象)
LocalDate tomorrow = today.plusDays(1);
LocalDate nextWeek = today.plusWeeks(1);
LocalDate lastMonth = today.minusMonths(1);
// 4. 日期比较
boolean isAfter = today.isAfter(birthday);
boolean isBefore = today.isBefore(LocalDate.of(2024, 1, 1));
boolean isLeapYear = today.isLeapYear();
// 5. 格式化与解析
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = current.format(formatter); // "2023-10-01 14:30:15"
LocalDateTime parsed = LocalDateTime.parse("2023-10-01 14:30:15", formatter);
// 6. 时区处理
ZonedDateTime zoned = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
ZonedDateTime newYorkTime = zoned.withZoneSameInstant(ZoneId.of("America/New_York"));
// 7. 时间差计算
Duration duration = Duration.between(startTime, endTime);
long hours = duration.toHours();
long minutes = duration.toMinutes();
Period period = Period.between(startDate, endDate);
int years = period.getYears();
int months = period.getMonths();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 1.6 其他重要特性
# 1.6.1 类型注解和重复注解
代码示例:
// 1. 类型注解(可用于任何类型使用的地方)
@NotNull String name = getName(); // 编译器检查非空
List<@Email String> emails; // 集合元素类型注解
// 2. 重复注解(同一个注解使用多次)
@Role("admin")
@Role("user")
class User {
// ...
}
// 定义可重复注解
@Repeatable(Roles.class)
@interface Role {
String value();
}
@interface Roles {
Role[] value(); // 容器注解
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1.6.2 StampedLock 锁优化
乐观读锁设计: StampedLock 就像图书馆的智能借阅系统,大部分读者可以快速浏览(乐观读),只有在真正需要修改时才上锁。
StampedLock 三种模式:
1. 写锁:独占锁,类似 ReentrantLock.writeLock()
2. 悲观读锁:共享锁,类似 ReentrantLock.readLock()
3. 乐观读:无锁读取,先获取戳记,验证时检查是否被修改
工作流程:
获取乐观读戳记 → 读取数据 → 验证戳记 → 有效则使用,无效则升级锁
↓ ↓
快速路径 回退路径
2
3
4
5
6
7
8
9
代码示例:
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
// 写操作使用写锁
void move(double deltaX, double deltaY) {
long stamp = sl.writeLock(); // 获取写锁
try {
x += deltaX;
y += deltaY;
} finally {
sl.unlockWrite(stamp); // 释放写锁
}
}
// 读操作使用乐观读
double distanceFromOrigin() {
long stamp = sl.tryOptimisticRead(); // 获取乐观读戳记
double currentX = x, currentY = y;
if (!sl.validate(stamp)) { // 检查期间是否有写操作
stamp = sl.readLock(); // 升级为悲观读锁
try {
currentX = x;
currentY = y;
} finally {
sl.unlockRead(stamp); // 释放读锁
}
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 1.6.3 JRE 精简和 PermGen 移除
Java 8 内存模型变化:
Java 7 及以前: Java 8:
┌─────────────────┐ ┌─────────────────┐
│ 堆(Heap) │ │ 堆(Heap) │
│ - Eden │ │ - Eden │
│ - Survivor │ │ - Survivor │
│ - Old Gen │ │ - Old Gen │
├─────────────────┤ ├─────────────────┤
│ 非堆内存 │ │ 非堆内存 │
│ - PermGen │ ← 移除 │ - Metaspace │ ← 新增
│ (方法区) │ │ (元空间) │
├─────────────────┤ ├─────────────────┤
│ JVM自身使用 │ │ JVM自身使用 │
│ - 代码缓存 │ │ - 代码缓存 │
└─────────────────┘ └─────────────────┘
关键改进:
1. PermGen → Metaspace
- 位置:从JVM内存移到本地内存
- 大小:自动扩展,无固定上限
- 回收:随ClassLoader回收,减少Full GC
2. JRE精简:移除了很少使用的功能,减小安装包
- 移除Java DB (Derby)
- 移除JavaFX(单独提供)
- 移除VisualVM(单独提供)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 2. Java 8 到 Java 11 重要特性
# 2.1 局部变量类型推断 (var)
设计思想: var 关键字就像智能标签,编译器能根据"内容"推断"容器"类型,让代码更简洁但不损失类型安全。
// Java 10+ 使用 var
var list = new ArrayList<String>(); // 推断为 ArrayList<String>
var stream = list.stream(); // 推断为 Stream<String>
var map = new HashMap<String, Integer>(); // 推断为 HashMap<String, Integer>
// 等价于传统写法
ArrayList<String> list = new ArrayList<String>();
Stream<String> stream = list.stream();
HashMap<String, Integer> map = new HashMap<String, Integer>();
// 限制:必须初始化,不能为null,不能用于lambda
var nullVar = null; // 编译错误:不能推断类型
var lambda = () -> "hello"; // 编译错误:不能用于lambda
2
3
4
5
6
7
8
9
10
11
12
13
# 2.2 HTTP Client API (标准化)
代码示例:
// Java 11 引入标准 HTTP Client
import java.net.http.*;
import java.net.URI;
import java.time.Duration;
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.version(HttpClient.Version.HTTP_2) // 支持HTTP/2
.build();
// 同步请求
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/data"))
.header("Content-Type", "application/json")
.GET()
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
// 异步请求
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 2.3 字符串增强
// 1. 重复字符串
String repeated = "Java ".repeat(3); // "Java Java Java "
// 2. 判断空白字符串
boolean blank1 = " ".isBlank(); // true(空格、制表符等)
boolean blank2 = "".isBlank(); // true
boolean empty = "".isEmpty(); // true(只有isEmpty时为空)
// 3. 去除首尾空白(支持Unicode)
String stripped = " hello ".strip(); // "hello"
String leading = " hello ".stripLeading(); // "hello "
String trailing = " hello ".stripTrailing(); // " hello"
// 4. 按行分割为Stream
String multiline = "第一行\n第二行\n第三行";
multiline.lines() // 返回Stream<String>
.filter(line -> !line.isBlank())
.forEach(System.out::println);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 2.4 单文件源代码程序
设计思想: 让Java像脚本语言一样可以直接运行单个文件,无需先编译再运行。
// HelloWorld.java(可以直接运行)
#!/usr/bin/env java --source 11
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
// 运行方式:
// java HelloWorld.java
// 无需先编译:javac HelloWorld.java
2
3
4
5
6
7
8
9
10
11
12
# 3. Java 11 到 Java 17 重要特性
# 3.1 密封类 (Sealed Classes)
设计思想: 密封类就像有限制的继承体系,明确指定哪些类可以继承,防止随意扩展,增强代码安全性。
// Java 17 密封类
public sealed class Shape
permits Circle, Rectangle, Triangle { // 只允许这三个子类
// 父类定义
}
// 子类必须声明为 final、sealed 或 non-sealed
public final class Circle extends Shape { /* ... */ }
public non-sealed class Rectangle extends Shape { /* ... */ }
public sealed class Triangle extends Shape permits Equilateral { /* ... */ }
public final class Equilateral extends Triangle { /* ... */ }
// 模式匹配中使用
double area = switch (shape) {
case Circle c -> Math.PI * c.radius() * c.radius();
case Rectangle r -> r.width() * r.height();
case Triangle t -> 0.5 * t.base() * t.height();
// 不需要default,因为所有子类都已处理
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 3.2 模式匹配 (Pattern Matching)
代码演进:
// Java 16 前:繁琐的类型检查和转换
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
// Java 16+:模式匹配简化
if (obj instanceof String s) { // 同时检查和转换
System.out.println(s.length());
}
// switch 表达式 + 模式匹配 (Java 17预览)
String formatted = switch (obj) {
case Integer i -> String.format("整数: %d", i);
case Long l -> String.format("长整数: %d", l);
case Double d -> String.format("小数: %f", d);
case String s -> String.format("字符串: %s", s);
default -> "其他类型";
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 3.3 文本块 (Text Blocks)
多行字符串简化:
// 传统方式(繁琐)
String html = "<html>\n" +
" <body>\n" +
" <p>Hello, world!</p>\n" +
" </body>\n" +
"</html>\n";
// Java 15+ 文本块(更清晰)
String html = """
<html>
<body>
<p>Hello, world!</p>
</body>
</html>
""";
// JSON 示例
String json = """
{
"name": "张三",
"age": 25,
"hobbies": ["阅读", "编程", "音乐"]
}
""";
// 格式化控制
String text = """
姓名: %s
年龄: %d
""".formatted("李四", 30); // formatted 方法
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 3.4 Record 类 (数据载体类)
设计思想: Record 就像数据表的行记录,自动生成构造器、访问器、equals、hashCode、toString 方法,专注于数据传输。
传统 POJO 类: Record 类:
public class Person { public record Person(
private String name; String name,
private int age; int age,
String address
// 构造器、getter、setter ) {}
// equals、hashCode
// toString
// 大量样板代码
}
2
3
4
5
6
7
8
9
10
代码示例:
// 1. 定义 Record
public record Person(String name, int age, String address) {
// 可以添加自定义方法
public String greeting() {
return "Hello, I'm " + name;
}
// 可以重写自动生成的方法
@Override
public String toString() {
return name + " (" + age + "岁)";
}
}
// 2. 使用 Record
Person p1 = new Person("张三", 25, "北京");
Person p2 = new Person("张三", 25, "北京");
System.out.println(p1.name()); // 访问器:张三
System.out.println(p1.age()); // 25
System.out.println(p1.equals(p2)); // true(自动实现)
System.out.println(p1); // 张三 (25岁)
// 3. 解构模式 (Java 21预览)
if (p1 instanceof Person(String name, int age, String address)) {
System.out.println(name + "住在" + address);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 4. Java 17 到 Java 21 重要特性
# 4.1 虚拟线程 (Virtual Threads)
设计思想: 传统线程像真实员工,创建成本高、数量有限。虚拟线程像机器人,创建快、数量多,由少量平台线程调度执行。
传统线程模型: 虚拟线程模型:
┌─────────────┐ ┌─────────────┐
│ 平台线程1 │ │ 平台线程1 │
│ ┌─────────┐ │ │ ┌─────────┐ │
│ │ 任务A │ │ │ │虚拟线程A│ │
│ └─────────┘ │ │ └─────────┘ │
└─────────────┘ │ ┌─────────┐ │
┌─────────────┐ │ │虚拟线程B│ │
│ 平台线程2 │ │ └─────────┘ │
│ ┌─────────┐ │ │ ┌─────────┐ │
│ │ 任务B │ │ │ │虚拟线程C│ │
│ └─────────┘ │ │ └─────────┘ │
└─────────────┘ └─────────────┘
创建10K线程 → 崩溃 创建10K虚拟线程 → 轻松
2
3
4
5
6
7
8
9
10
11
12
13
14
代码示例:
// Java 21 虚拟线程
// 1. 创建虚拟线程
Thread virtualThread = Thread.ofVirtual()
.name("virtual-thread-", 0)
.start(() -> {
System.out.println("Hello from virtual thread");
});
// 2. 使用 ExecutorService
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
System.out.println(i);
return i;
});
});
} // executor.close() 自动调用
// 3. 结构化并发 (Java 21预览)
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future<String> user = scope.fork(() -> fetchUser());
Future<Integer> order = scope.fork(() -> fetchOrder());
scope.join(); // 等待所有任务
scope.throwIfFailed(); // 传播异常
System.out.println("User: " + user.resultNow());
System.out.println("Order: " + order.resultNow());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 4.2 序列集合 (Sequenced Collections)
设计思想: 为集合接口添加明确的顺序操作,提供统一的 first/last 访问方法。
// Java 21 序列集合
// SequencedCollection, SequencedSet, SequencedMap
// 1. SequencedCollection (有序集合)
SequencedCollection<String> seq = new ArrayList<>();
seq.add("A");
seq.add("B");
seq.add("C");
System.out.println(seq.getFirst()); // "A"
System.out.println(seq.getLast()); // "C"
seq.addFirst("Start"); // [Start, A, B, C]
seq.addLast("End"); // [Start, A, B, C, End]
// 2. SequencedMap (有序映射)
SequencedMap<Integer, String> map = new LinkedHashMap<>();
map.put(1, "One");
map.put(2, "Two");
map.put(3, "Three");
System.out.println(map.firstEntry()); // 1=One
System.out.println(map.lastEntry()); // 3=Three
// 反向视图
SequencedMap<Integer, String> reversed = map.reversed();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 4.3 switch 模式匹配增强
代码示例:
// Java 21 switch 模式匹配
Object obj = "Hello";
// 1. 类型模式 + 守卫条件
String result = switch (obj) {
case null -> "null";
case String s when s.length() > 5 -> "长字符串: " + s;
case String s -> "字符串: " + s;
case Integer i -> "整数: " + i;
case int[] array when array.length == 0 -> "空数组";
case int[] array -> "数组长度: " + array.length;
default -> "其他";
};
// 2. Record 模式匹配
record Point(int x, int y) {}
record Circle(Point center, int radius) {}
Object shape = new Circle(new Point(0, 0), 10);
if (shape instanceof Circle(Point center, int radius)) {
System.out.println("圆心: (" + center.x() + "," + center.y() + ")");
}
// 3. 嵌套模式匹配
double area = switch (shape) {
case Circle(Point(var x, var y), var r) -> Math.PI * r * r;
case Rectangle(Point p1, Point p2) ->
Math.abs((p2.x() - p1.x()) * (p2.y() - p1.y()));
default -> 0;
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 4.4 分代 ZGC (Generational ZGC)
垃圾回收优化:
// Java 21 ZGC 分代收集
// 启动参数
// -XX:+UseZGC -XX:+ZGenerational
// ZGC 分代优势:
// 年轻代:高频收集,快速回收短命对象
// 老年代:低频收集,减少停顿时间
// 性能对比:
// 吞吐量提升:10-30%
// 最大停顿时间:<1ms
2
3
4
5
6
7
8
9
10
11
# 5. Java 22+ 新特性概述
# 5.1 字符串模板 (预览)
// Java 22 字符串模板(预览)
import static java.lang.StringTemplate.*;
// 1. STR 模板处理器
String name = "Alice";
int age = 25;
String message = STR."Hello, \{name}! You are \{age} years old.";
// 结果:Hello, Alice! You are 25 years old.
// 2. FMT 格式化模板
double price = 19.99;
String formatted = FMT."价格: %8.2f\{price}";
// 结果:价格: 19.99
// 3. 自定义模板处理器
StringTemplate st = RAW."用户 \{name} 年龄 \{age}";
String result = st.process(StringTemplate::interpolate);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 5.2 未命名变量和模式
// Java 22 未命名变量
// 1. 忽略不需要的变量
try {
int result = Integer.parseInt("123");
} catch (NumberFormatException _) { // 使用 _ 忽略异常变量
System.out.println("解析失败");
}
// 2. 忽略不需要的lambda参数
list.forEach(_ -> System.out.println("元素"));
// 3. 忽略记录组件
record Person(String name, int age, String _) {} // 忽略地址
// 4. 模式匹配中忽略部分
if (obj instanceof Point(int x, int _)) { // 忽略y坐标
System.out.println("x = " + x);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 5.3 结构化并发 (正式)
// Java 22 结构化并发(正式)
Response handle() throws ExecutionException, InterruptedException {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future<String> user = scope.fork(() -> findUser());
Future<Integer> order = scope.fork(() -> fetchOrder());
scope.join(); // 等待两个任务
scope.throwIfFailed(); // 如果失败则抛出异常
return new Response(user.resultNow(), order.resultNow());
}
// 自动取消未完成的任务
}
2
3
4
5
6
7
8
9
10
11
12
13
# 5.4 Vector API (第七次孵化)
// Java 22 Vector API(用于向量计算)
static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED;
void vectorComputation(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
var m = SPECIES.indexInRange(i, a.length);
FloatVector va = FloatVector.fromArray(SPECIES, a, i, m);
FloatVector vb = FloatVector.fromArray(SPECIES, b, i, m);
FloatVector vc = va.mul(va) // a²
.add(vb.mul(vb)) // + b²
.sqrt(); // √(a²+b²)
vc.intoArray(c, i, m);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 6. 各版本关键特性总结
# 6.1 版本演进路线图
Java 版本演进(LTS版本重点):
┌─────────┬─────────┬─────────┬─────────┬─────────┐
│ Java 8 │ Java 11 │ Java 17 │ Java 21 │ Java 25 │
│ (2014) │ (2018) │ (2021) │ (2023) │ (2025?) │
├─────────┼─────────┼─────────┼─────────┼─────────┤
│ Lambda │ var │ 密封类 │虚拟线程 │ 待定 │
│ Stream │HTTP客户端│ Record │结构化并发│ │
│ Optional│ 字符串增强│文本块 │序列集合 │ │
│ 新日期API│ │模式匹配 │分代ZGC │ │
│ 默认方法 │ │ │ │ │
└─────────┴─────────┴─────────┴─────────┴─────────┘
2
3
4
5
6
7
8
9
10
11
# 6.2 升级建议
从 Java 8 升级:
先升级到 Java 11 LTS
- 语法:使用 var 简化类型声明
- API:使用新的 HTTP Client、字符串方法
- 工具:使用单文件源代码执行
再升级到 Java 17 LTS
- 语法:使用 Record、文本块、密封类
- 模式:使用模式匹配简化代码
- 性能:使用 ZGC 改进垃圾回收
最后升级到 Java 21+
- 并发:使用虚拟线程处理高并发
- 集合:使用序列集合统一API
- 开发:使用结构化并发管理任务
# 6.3 特性应用场景
根据需求选择特性:
// 高并发场景:Java 21+ 虚拟线程
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
// 处理大量并发任务
}
// 数据处理场景:Java 8+ Stream API
data.stream()
.filter(...)
.map(...)
.collect(...);
// API开发场景:Java 11+ HTTP Client
HttpClient.newHttpClient().send(...);
// 数据模型场景:Java 16+ Record
public record User(String name, int age) {}
// 字符串处理:Java 15+ 文本块
String json = """
{ "name": "value" }
""";
// 模式匹配:Java 17+ switch表达式
String result = switch (obj) {
case String s -> "字符串";
case Integer i -> "整数";
default -> "其他";
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 7. 实践示例:综合运用新特性
# 7.1 现代化 Java 代码示例
// 综合使用 Java 8-21 特性的示例
import java.net.http.*;
import java.net.URI;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;
public class ModernJavaExample {
// 使用 Record 定义数据模型
public record User(String id, String name, int age, List<String> roles) {}
// 使用密封类定义操作类型
public sealed interface Operation
permits CreateOp, UpdateOp, DeleteOp {}
public record CreateOp(User user) implements Operation {}
public record UpdateOp(String id, User user) implements Operation {}
public record DeleteOp(String id) implements Operation {}
public static void main(String[] args) {
// 使用虚拟线程执行器
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
// 并行处理用户数据
List<Future<User>> futures = IntStream.range(0, 10)
.mapToObj(i -> executor.submit(() -> fetchUser(i)))
.toList();
// 收集结果
List<User> users = futures.stream()
.map(future -> {
try {
return future.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
})
.filter(user -> user.age() >= 18)
.sorted(Comparator.comparing(User::name))
.toList();
// 使用模式匹配处理操作
Operation op = new CreateOp(new User("1", "Alice", 25, List.of("admin")));
String result = switch (op) {
case CreateOp(User user) ->
STR."创建用户: \{user.name()},角色: \{String.join(",", user.roles())}";
case UpdateOp(String id, User user) ->
STR."更新用户 \{id}: \{user.name()}";
case DeleteOp(String id) ->
STR."删除用户: \{id}";
};
System.out.println(result);
// 使用 HTTP Client 调用外部API
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/users"))
.header("Content-Type", "application/json")
.build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
}
}
private static User fetchUser(int id) {
// 模拟从数据库获取用户
return new User(
String.valueOf(id),
"User" + id,
20 + id,
List.of("user")
);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# 7.2 性能优化示例
// 使用新特性优化性能
public class PerformanceOptimization {
// 1. 使用 Record 减少内存占用
public record EfficientData(int id, String name, double value) {}
// 2. 使用虚拟线程处理IO密集型任务
public CompletableFuture<List<String>> fetchUrls(List<String> urls) {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
List<Future<String>> futures = urls.stream()
.map(url -> scope.fork(() -> fetchUrl(url)))
.toList();
scope.join();
scope.throwIfFailed();
return CompletableFuture.completedFuture(
futures.stream()
.map(Future::resultNow)
.toList()
);
} catch (Exception e) {
return CompletableFuture.failedFuture(e);
}
}
// 3. 使用 Vector API 进行数值计算优化
public void vectorizedComputation(float[] array) {
var species = FloatVector.SPECIES_PREFERRED;
for (int i = 0; i < array.length; i += species.length()) {
var mask = species.indexInRange(i, array.length);
var vector = FloatVector.fromArray(species, array, i, mask);
// 向量化运算
var result = vector.mul(vector).add(vector).sqrt();
result.intoArray(array, i, mask);
}
}
private String fetchUrl(String url) {
// 模拟HTTP请求
return "Response from " + url;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 总结
Java 从版本 8 到 25 的演进,体现了从面向对象到函数式、从重量级到轻量级、从复杂到简洁的转变。关键趋势包括:
- 简洁性:var、Record、文本块等减少样板代码
- 安全性:密封类、Optional 等增强类型安全
- 并发性:虚拟线程、结构化并发改进并发编程
- 性能:ZGC、Vector API 等提升运行时性能
- 现代化:模式匹配、HTTP Client 等提供现代编程体验
建议根据项目需求选择合适的版本升级,优先采用 LTS 版本(8、11、17、21),逐步引入新特性改进代码质量和性能。