Java版本的演变

2025/11/24 规范JDK

# 📊 Java 版本演进概览

从 Java 8 (2014年3月) 到 Java 21 (2023年9月),跨越了13个主要版本,历时9年半

Java 8 → 9 → 10 → 11 → 12 → 13 → 14 → 15 → 16 → 17 → 18 → 19 → 20 → 21
(2014)          (2018)                        (2021)			  (2023)			  
1
2

版本发布节奏变化

  • 2017年前:每2-3年一个大版本
  • 2017年后:每6个月一个功能版本,每3年一个LTS版本

LTS版本重要性

  • Java 8、11、17、21 是长期支持版本
  • 企业生产环境首选,提供长期安全更新和支持

# 🎯 各版本主要特性详解

# 1. Java 8 (2014) - 里程碑版本

// Lambda 表达式 - 函数式编程
List<String> list = Arrays.asList("a", "b", "c");
list.forEach(item -> System.out.println(item));

// Stream API - 流式处理
List<String> result = list.stream()
    .filter(s -> s.startsWith("a"))
    .map(String::toUpperCase)
    .collect(Collectors.toList());

// 方法引用
list.forEach(System.out::println);

// Optional 避免空指针
Optional<String> optional = Optional.ofNullable(getName());
String name = optional.orElse("默认名称");

// 新的日期时间
LocalDateTime updateTime = LocalDateTime.now();
String format = updateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

核心特性

  • Lambda 表达式 - 函数式编程基础
  • Stream API - 声明式数据处理
  • 方法引用 - 简化代码
  • 默认方法 - 接口演进
  • 新的日期时间 API (java.time) - 替代易错的Date/Calendar
  • Optional 类 - 优雅处理null
  • Nashorn JavaScript 引擎 - 在JVM上运行JS

生产影响:绝大多数企业从Java 7升级到8,性能提升显著

# 2. Java 9 (2017) - 模块化革命

// 模块化系统 - module-info.java
module com.mycompany.app {
    requires java.base;
    requires java.sql;
    requires transitive java.xml;  // 传递依赖
    exports com.mycompany.api;
    exports com.mycompany.internal to com.mycompany.test;
}

// 集合工厂方法 - 创建不可变集合
List<String> list = List.of("a", "b", "c");
Set<String> set = Set.of("a", "b");
Map<String, Integer> map = Map.of("a", 1, "b", 2);
Map<String, Integer> complexMap = Map.ofEntries(
    Map.entry("a", 1),
    Map.entry("b", 2)
);

// 接口私有方法
public interface Calculator {
    default void log(String message) {
        doLog(message);
    }
    
    private void doLog(String message) {
        System.out.println("LOG: " + message);
    }
}
1
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

核心特性

  • 模块系统 (Project Jigsaw) - 解决"JAR地狱"
  • JShell (REPL工具) - 交互式编程
  • 集合工厂方法 - 简洁的不可变集合创建
  • 接口私有方法 - 接口内部代码复用
  • 改进的 Stream API - takeWhile,dropWhile,ofNullable
  • 多版本JAR - 支持不同Java版本的类文件
  • HTTP/2客户端 (孵化) - 现代HTTP协议支持

迁移挑战:模块化系统对大型项目影响较大,需要重新设计包结构

# 3. Java 10 (2018) - 局部变量推断

// 局部变量类型推断
var list = new ArrayList<String>();  // 推断为 ArrayList<String>
var map = new HashMap<String, Integer>();
var stream = list.stream();

// 在循环中使用
for (var item : list) {
    System.out.println(item);
}

// 传统写法对比
ArrayList<String> explicitList = new ArrayList<String>();
1
2
3
4
5
6
7
8
9
10
11
12

注意事项

  • var 只能用于局部变量
  • 必须初始化,不能为null
  • 不能用于方法参数、返回类型、字段

核心特性

  • 局部变量类型推断 (var) - 减少样板代码
  • 并行全垃圾回收器 G1 - 改善GC性能
  • 应用类数据共享 - 启动速度优化
  • 根证书更新 - 安全增强

# 4. Java 11 (2018) - LTS 长期支持版

// HTTP Client API (正式)
HttpClient client = HttpClient.newBuilder()
    .version(HttpClient.Version.HTTP_2)
    .connectTimeout(Duration.ofSeconds(10))
    .build();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/users"))
    .header("Content-Type", "application/json")
    .timeout(Duration.ofSeconds(5))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, 
    HttpResponse.BodyHandlers.ofString());

// 字符串新增方法
String text = "  Hello World  ";
System.out.println(text.isBlank());      // false
System.out.println(text.strip());        // "Hello World"
System.out.println("Java\nJava\nJava".lines().count());  // 3
System.out.println("Java".repeat(3));    // "JavaJavaJava"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

核心特性

  • HTTP Client API (正式) - 替代HttpURLConnection
  • 局部变量语法扩展 - Lambda参数使用var
  • 字符串新增方法 - isBlank, lines, repeat, strip
  • 直接运行单文件源码 - java HelloWorld.java
  • Epsilon垃圾收集器 - 无操作GC,用于性能测试
  • Flight Recorder - 开源的生产级性能分析工具
  • TLS 1.3支持 - 安全协议升级

重要变化:移除了Java EE和CORBA模块,需要手动添加依赖

# 5. Java 12-15 - 持续创新期

# Java 12 (2019)

// Switch表达式 (预览)
int day = 3;
String dayType = switch (day) {
    case 1, 2, 3, 4, 5 -> "工作日";
    case 6, 7 -> "周末";
    default -> "无效";
};

// 传统switch对比
String traditionalDayType;
switch (day) {
    case 1: case 2: case 3: case 4: case 5:
        traditionalDayType = "工作日";
        break;
    case 6: case 7:
        traditionalDayType = "周末";
        break;
    default:
        traditionalDayType = "无效";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

核心特性

  • Switch表达式 (预览) - 更简洁的switch语法
  • Shenandoah垃圾收集器 - 低暂停时间GC
  • 微基准测试套件 - JMH成为标准组件

# Java 13 (2019)

// 文本块 (预览) - 处理多行字符串
String json = """
    {
        "name": "张三",
        "age": 30,
        "hobbies": ["阅读", "运动"]
    }
    """;

String html = """
    <html>
        <body>
            <h1>标题</h1>
            <p>段落内容</p>
        </body>
    </html>
    """;

// 传统方式对比
String oldJson = "{\n" +
                 "    \"name\": \"张三\",\n" +
                 "    \"age\": 30\n" +
                 "}";
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

核心特性

  • 文本块 (预览) - 简化多行字符串处理
  • 增强的Switch表达式 - 引入yield返回值
  • 动态CDS存档 - 改进类数据共享
  • ZGC优化 - 返回未使用的堆内存

# Java 14 (2020)

// instanceof模式匹配
if (obj instanceof String str) {
    return str.length();  // 直接使用str,无需强制转换
}

// 记录类 (预览) - 数据传输对象
public record Person(String name, int age, String email) {
    // 可以添加自定义方法
    public boolean isAdult() {
        return age >= 18;
    }
}

// 使用记录类
Person person = new Person("李四", 25, "lisi@example.com");
String name = person.name();  // 自动生成的访问器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

核心特性

  • instanceof模式匹配 - 简化类型检查和转换
  • 记录类 (预览) - 不可变数据载体
  • 有用的NullPointerExceptions - 详细错误信息
  • 打包工具 (Incubator) - 创建本地安装包
  • G1改进 - NUMA感知内存分配

# Java 15 (2020)

// 文本块正式化,新增转义序列
String query = """
    SELECT id, name, email \
    FROM users \
    WHERE status = 'ACTIVE'""";

// 隐藏类 - 框架开发利器
public class HiddenClassDemo {
    public static void main(String[] args) throws Exception {
        // 动态创建类,对反射不可见
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

核心特性

  • 文本块 (正式) - 多行字符串成为标准
  • 密封类 (预览) - 控制类的继承
  • 隐藏类 - 框架开发的利器
  • ZGC和Shenandoah成为生产特性 - 替代并行GC的选择
  • 移除了Nashorn JavaScript引擎 - 推荐使用GraalVM

# 6. Java 16 (2021) - 模式匹配成熟

// 记录类正式化
public record Point(int x, int y) {
    // 紧凑构造器
    public Point {
        if (x < 0 || y < 0) {
            throw new IllegalArgumentException("坐标不能为负");
        }
    }
    
    // 自定义方法
    public double distanceTo(Point other) {
        return Math.hypot(x - other.x, y - other.y);
    }
}

// instanceof模式匹配正式化
public boolean equals(Object obj) {
    return obj instanceof Point p && 
           p.x == this.x && p.y == this.y;
}

// Stream.toList() 简化
List<String> filtered = list.stream()
    .filter(s -> s.length() > 3)
    .toList();  // 替代 .collect(Collectors.toList())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

核心特性

  • 记录类 (正式) - 简化DTO创建
  • instanceof模式匹配 (正式) - 类型安全转换
  • Stream.toList() 方法 - 简化终端操作
  • Vector API (孵化) - 硬件向量计算
  • Unix域套接字通道 - 本地进程通信
  • 弹性元空间 - 自动返回未使用的元空间内存

# 7. Java 17 (2021) - LTS 长期支持版

// 密封类和接口
public sealed interface Shape 
    permits Circle, Rectangle, Triangle {
    
    double area();
    double perimeter();
}

public final class Circle implements Shape {
    private final double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public double perimeter() {
        return 2 * Math.PI * radius;
    }
}

public non-sealed class Rectangle implements Shape {
    private final double width, height;
    // 实现...
}

public final class Triangle implements Shape {
    // 实现...
}
1
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

核心特性

  • 密封类 (正式) - 精确控制继承层次
  • 模式匹配 Switch (预览) - 强大的switch能力
  • 新的随机数生成器 - 更现代API
  • 上下文特定的反序列化过滤器 - 安全增强
  • 移除Applet API - 彻底告别浏览器插件
  • 强封装JDK内部API - 安全性和模块化

# 8. Java 18 (2022)

// 简单的Web服务器
// 命令行启动: jwebserver
// 或在代码中:
HttpServer server = HttpServer.create(/* 配置 */);

// UTF-8作为默认字符集
// 在所有操作系统上保持一致行为
1
2
3
4
5
6
7

核心特性

  • 简单的Web服务器 - 静态文件服务工具
  • UTF-8作为默认字符集 - 跨平台一致性
  • 代码片段 (JShell) - 文档中嵌入可执行代码
  • 互联网地址解析SPI - 自定义网络地址解析
  • Vector API (第三次孵化) - 持续改进

# 9. Java 19 (2022) - 并发革命

// 虚拟线程 - 项目Loom (预览)
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    List<Future<Integer>> futures = new ArrayList<>();
    
    for (int i = 0; i < 10_000; i++) {
        futures.add(executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1));
            return 42;
        }));
    }
    
    // 处理结果...
}

// 结构化并发 (孵化)
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());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

核心特性

  • 虚拟线程 (预览) - 轻量级并发,百万级线程
  • 结构化并发 (孵化) - 简化并发编程
  • Vector API (第四次孵化) - Llama3.java依赖的关键特性
  • 外部函数和内存API (预览) - 替代JNI的现代方案
  • Linux/RISC-V端口 - 支持新兴架构

# 10. Java 20 (2023)

// 虚拟线程 (第二次预览)
// 使用方式与Java 19类似,API更加稳定

// 作用域值 (孵化) - 替代线程局部变量
public class ScopedValueExample {
    private static final ScopedValue<User> CURRENT_USER = ScopedValue.newInstance();
    
    public void processRequest(Request request) {
        User user = authenticate(request);
        ScopedValue.runWhere(CURRENT_USER, user, () -> {
            handleRequest(request);
        });
    }
    
    private void handleRequest(Request request) {
        User user = CURRENT_USER.get();  // 在当前作用域内可用
        // 处理请求...
    }
}

// 记录模式 (预览)
static void printSum(Object obj) {
    if (obj instanceof Point(int x, int y)) {
        System.out.println(x + y);
    }
}
1
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

核心特性

  • 虚拟线程 (第二次预览) - API改进
  • 作用域值 (孵化) - 替代线程局部变量
  • 记录模式 (预览) - 解构记录对象
  • Vector API (第五次孵化) - 接近正式版
  • 结构化并发 (第二次孵化) - API稳定

# 11. Java 21 (2023) - LTS 重大更新

// 虚拟线程正式发布
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();

// 提交10万个任务
for (int i = 0; i < 100_000; i++) {
    executor.submit(() -> {
        Thread.sleep(Duration.ofSeconds(1));
        return processTask(i);
    });
}

// 记录模式和Switch模式匹配
static String format(Object obj) {
    return switch (obj) {
        case Point(int x, int y) -> 
            String.format("Point(%d, %d)", x, y);
        case Circle(Point center, int radius) -> 
            String.format("Circle(center=%s, radius=%d)", center, radius);
        case null -> "null";
        default -> obj.toString();
    };
}

// 序列化集合
public class CollectionSerialization {
    public void example() {
        List<String> list = List.of("a", "b", "c");
        Set<Integer> set = Set.of(1, 2, 3);
        // 这些集合现在支持序列化
    }
}
1
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

核心特性

  • 虚拟线程 (正式) - 并发编程的革命
  • 记录模式 (正式) - 强大的数据解构
  • Switch模式匹配 (正式) - 模式匹配的完全体
  • 序列化集合 - 不可变集合支持序列化
  • 分代ZGC - 垃圾收集器性能提升
  • 密钥封装机制API - 后量子密码学
  • 弃用Windows 32位x86端口 - 推进64位化

# 12. Java 22 (2024)

# 未命名变量与模式

// 传统方式 - 需要给不使用的变量命名
try {
    int result = calculate();
} catch (Exception e) {
    // 不使用异常对象但仍需命名
    System.out.println("计算失败");
}

// Java 22 - 使用下划线忽略未使用变量
try {
    int result = calculate();
} catch (Exception _) {  // 使用_忽略异常对象
    System.out.println("计算失败");
}

// 在for循环中忽略元素
List<Person> people = getPeople();
for (int i = 0; i < people.size(); i++) {
    var _ = people.get(i);  // 忽略具体元素,只关心大小
    System.out.println("处理第" + i + "个人");
}

// 多重赋值中忽略某些值
Point[] points = getPoints();
for (Point(_, int y) : points) {  // 只关心y坐标
    System.out.println("Y坐标: " + y);
}
1
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

# 字符串模板 (第二次预览)

// 传统字符串拼接
String name = "张三";
int age = 25;
String message = "姓名:" + name + ",年龄:" + age;

// Java 22 字符串模板
import static java.lang.StringTemplate.STR;

String message = STR."姓名:\{name},年龄:\{age}";

// 更复杂的例子
public class StringTemplateDemo {
    public static void main(String[] args) {
        String user = "李四";
        double score = 95.5;
        boolean passed = true;
        
        String result = STR."""
            学生信息:
            姓名:\{user}
            分数:\{score}
            状态:\{passed ? "及格" : "不及格"}
            评估时间:\{java.time.LocalDateTime.now()}
            """;
        System.out.println(result);
    }
}

// 自定义模板处理器
StringTemplate.Processor<String, RuntimeException> JSON = StringTemplate.Processor.of(
    (StringTemplate st) -> {
        // 自定义JSON格式处理
        return "自定义格式";
    }
);
1
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

# 流收集器 (预览)

import java.util.stream.*;
import java.util.*;

public class StreamGatherersDemo {
    public static void main(String[] args) {
        List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        // 窗口收集器 - 创建滑动窗口
        List<List<Integer>> windows = numbers.stream()
            .gather(Gatherers.windowSliding(3))
            .toList();
        // 结果: [[1,2,3], [2,3,4], [3,4,5], ...]
        
        // 固定窗口
        List<List<Integer>> fixedWindows = numbers.stream()
            .gather(Gatherers.windowFixed(2))
            .toList();
        // 结果: [[1,2], [3,4], [5,6], ...]
        
        // 折叠收集器 - 累积操作
        List<String> folded = Stream.of("a", "b", "c", "d")
            .gather(Gatherers.fold(() -> "", (acc, elem) -> acc + elem))
            .toList();
        // 结果: ["a", "ab", "abc", "abcd"]
        
        // 扫描收集器 - 类似reduce但保留中间结果
        List<Integer> scanned = numbers.stream()
            .gather(Gatherers.scan(() -> 0, Integer::sum))
            .toList();
        // 结果: [1, 3, 6, 10, 15, ...] (累加和)
            
        // 去重相邻重复项
        List<Integer> numbersWithDupes = List.of(1, 1, 2, 3, 3, 3, 4, 2, 2);
        List<Integer> distinctAdjacent = numbersWithDupes.stream()
            .gather(Gatherers.distinct())
            .toList();
        // 结果: [1, 2, 3, 4, 2]
    }
}
1
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

核心特性

  • 未命名变量与模式:允许使用下划线 _ 表示未使用的变量或模式组件,减少视觉干扰和错误可能。
  • 字符串模板 (第二次预览):简化包含运行时计算值的字符串的表达,并提高由用户提供值的程序的安全性。
  • 流收集器 (预览):增强了Stream API,支持自定义中间操作,使数据转换更加灵活和高效。
  • 外部函数与内存 API:提供了一个API,使Java程序能够与Java运行时外部的代码和数据进行交互,提高了易用性、灵活性、安全性和性能。

# 13. Java 23 (2024)

# 向量 API (正式版)

import jdk.incubator.vector.*;

public class VectorAPIDemo {
    // 使用向量API进行高性能数组计算
    public static void vectorAdd(float[] a, float[] b, float[] c) {
        var species = FloatVector.SPECIES_PREFERRED;
        int i = 0;
        int upperBound = species.loopBound(a.length);
        
        for (; i < upperBound; i += species.length()) {
            // 加载向量
            var va = FloatVector.fromArray(species, a, i);
            var vb = FloatVector.fromArray(species, b, i);
            
            // 向量加法
            var vc = va.add(vb);
            
            // 存储结果
            vc.intoArray(c, i);
        }
        
        // 处理剩余元素
        for (; i < a.length; i++) {
            c[i] = a[i] + b[i];
        }
    }
    
    // AI推理中的矩阵乘法优化
    public static float[] optimizedMatrixMultiply(float[][] matrix, float[] vector) {
        float[] result = new float[matrix.length];
        var species = FloatVector.SPECIES_256;
        
        for (int i = 0; i < matrix.length; i++) {
            var sum = FloatVector.zero(species);
            float[] row = matrix[i];
            
            int j = 0;
            for (; j < species.loopBound(row.length); j += species.length()) {
                var rowVector = FloatVector.fromArray(species, row, j);
                var vecVector = FloatVector.fromArray(species, vector, j);
                sum = sum.add(rowVector.mul(vecVector));
            }
            
            result[i] = sum.reduceLanes(VectorOperators.ADD);
            
            // 处理尾部元素
            for (; j < row.length; j++) {
                result[i] += row[j] * vector[j];
            }
        }
        return result;
    }
    
    // 复杂向量操作 - 点积计算
    public static float vectorDotProduct(float[] a, float[] b) {
        var species = FloatVector.SPECIES_PREFERRED;
        var sum = FloatVector.zero(species);
        int i = 0;
        int upperBound = species.loopBound(a.length);
        
        for (; i < upperBound; i += species.length()) {
            var va = FloatVector.fromArray(species, a, i);
            var vb = FloatVector.fromArray(species, b, i);
            sum = sum.add(va.mul(vb));
        }
        
        float result = sum.reduceLanes(VectorOperators.ADD);
        
        // 标量尾部处理
        for (; i < a.length; i++) {
            result += a[i] * b[i];
        }
        
        return result;
    }
}
1
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

# 结构化并发 (正式版)

import java.util.concurrent.*;
import java.util.*;

public class StructuredConcurrencyDemo {
    public record UserInfo(String name, int age, List<String> orders) {}
    
    public UserInfo fetchUserData(String userId) throws ExecutionException, InterruptedException {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            // 并行执行多个任务
            Future<String> userName = scope.fork(() -> fetchUserName(userId));
            Future<Integer> userAge = scope.fork(() -> fetchUserAge(userId));
            Future<List<String>> userOrders = scope.fork(() -> fetchUserOrders(userId));
            
            // 等待所有任务完成或任何一个失败
            scope.join();
            scope.throwIfFailed();  // 如果有任务失败会抛出异常
            
            // 组合结果
            return new UserInfo(userName.resultNow(), userAge.resultNow(), userOrders.resultNow());
        }
    }
    
    // 处理多个并行请求,任一失败则取消所有
    public List<String> fetchMultipleUsers(List<String> userIds) {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            List<Future<String>> futures = userIds.stream()
                .map(id -> scope.fork(() -> fetchUserData(id).name()))
                .toList();
            
            scope.join();
            scope.throwIfFailed();
            
            return futures.stream()
                .map(Future::resultNow)
                .toList();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
    }
    
    private String fetchUserName(String userId) {
        // 模拟网络请求
        return "用户-" + userId;
    }
    
    private int fetchUserAge(String userId) {
        // 模拟数据库查询
        return 30;
    }
    
    private List<String> fetchUserOrders(String userId) {
        // 模拟API调用
        return List.of("订单1", "订单2", "订单3");
    }
}
1
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

# 流收集器 (第二次预览 - 更多示例)

import java.util.stream.*;
import java.util.*;

public class AdvancedGatherersDemo {
    public static void main(String[] args) {
        List<String> words = List.of("hello", "world", "java", "programming", "language");
        
        // 分组收集器 - 每2个元素一组
        List<List<String>> groups = words.stream()
            .gather(Gatherers.windowFixed(2))
            .toList();
        // 结果: [["hello", "world"], ["java", "programming"], ["language"]]
        
        // 去重相邻重复项
        List<Integer> numbersWithDupes = List.of(1, 1, 2, 3, 3, 3, 4, 2, 2);
        List<Integer> distinctAdjacent = numbersWithDupes.stream()
            .gather(Gatherers.distinct())
            .toList();
        // 结果: [1, 2, 3, 4, 2]
        
        // 自定义收集器 - 查找峰值
        Gatherer<Integer, ?, Integer> peakFinder = Gatherer.of(
            () -> new int[2], // 状态: [previous, currentPeak]
            (state, element, downstream) -> {
                if (state[1] == 0 || element > state[1]) {
                    state[1] = element;
                }
                if (state[0] != 0 && element < state[0]) {
                    downstream.push(state[1]);
                    state[1] = element;
                }
                state[0] = element;
                return true;
            },
            (state, downstream) -> {
                // 完成时推送最后一个峰值
                if (state[1] != 0) {
                    downstream.push(state[1]);
                }
            }
        );
        
        // 使用自定义收集器
        List<Integer> peaks = List.of(1, 3, 2, 5, 4, 6, 2).stream()
            .gather(peakFinder)
            .toList();
        // 结果: [3, 5, 6]
    }
}
1
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

核心特性

  • 向量 API:引入了向量计算API,使其在支持的CPU架构上能可靠地编译为向量指令,性能优于等效的标量计算。这对于Llama3.java这类需要高性能数值计算的项目至关重要
  • 流收集器 (第二次预览):在上一版本预览的基础上继续改进。
  • 结构化并发 (正式):通过引入结构化并发API,简化了错误处理和取消操作,并增强了并发代码的可观察性,帮助消除常见的取消和关闭风险。

# 14. Java 24 (2025) - 最新特性展望

# 模块化隐式声明类 (预览)

// 传统Java - 需要明确的类声明
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

// Java 24 - 隐式声明类 (简化入门)
void main() {
    println("Hello, World!");
    
    // 可以直接使用顶级函数
    var name = "Java 24";
    var message = "欢迎使用 " + name;
    println(message);
    
    // 支持顶级变量
    int count = 10;
    for (int i = 0; i < count; i++) {
        println("计数: " + i);
    }
}

// 其他顶级函数定义
void println(String text) {
    System.out.println(text);
}

int add(int a, int b) {
    return a + b;
}

// 这会被隐式编译为一个类,对初学者更友好
1
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

# 作用域值 (正式版)

import java.util.concurrent.*;

public class ScopedValuesDemo {
    // 定义作用域值
    private static final ScopedValue<UserContext> CURRENT_USER = ScopedValue.newInstance();
    private static final ScopedValue<Locale> USER_LOCALE = ScopedValue.newInstance();
    private static final ScopedValue<RequestId> REQUEST_ID = ScopedValue.newInstance();
    
    public void processUserRequest(String request) {
        UserContext user = authenticateUser(request);
        Locale locale = detectLocale(request);
        RequestId requestId = generateRequestId();
        
        // 在作用域内绑定值
        ScopedValue.where(CURRENT_USER, user)
                   .where(USER_LOCALE, locale)
                   .where(REQUEST_ID, requestId)
                   .run(() -> {
                       handleRequest(request);
                   });
    }
    
    private void handleRequest(String request) {
        // 在任何深度的方法调用中都可以访问作用域值
        UserContext user = CURRENT_USER.get();
        Locale locale = USER_LOCALE.get();
        RequestId requestId = REQUEST_ID.get();
        
        System.out.println("请求ID: " + requestId.id());
        System.out.println("处理用户 " + user.name() + " 的请求,语言: " + locale);
        processOrder(user, request);
    }
    
    private void processOrder(UserContext user, String request) {
        // 不需要传递用户上下文,直接通过作用域值获取
        if (!CURRENT_USER.get().hasPermission("ORDER_CREATE")) {
            throw new SecurityException("无权限创建订单");
        }
        
        // 创建订单逻辑...
        System.out.println("为用户 " + user.name() + " 创建订单");
        logAudit(user, "ORDER_CREATED");
    }
    
    private void logAudit(UserContext user, String action) {
        // 审计日志自动包含用户信息和请求ID
        System.out.printf("审计: 用户=%s, 操作=%s, 请求ID=%s%n",
            user.name(), action, REQUEST_ID.get().id());
    }
    
    record UserContext(String name, List<String> permissions) {
        boolean hasPermission(String permission) {
            return permissions.contains(permission);
        }
    }
    
    record RequestId(String id) {
        static RequestId generate() {
            return new RequestId(UUID.randomUUID().toString());
        }
    }
    
    private UserContext authenticateUser(String request) {
        return new UserContext("张三", List.of("ORDER_CREATE", "USER_READ"));
    }
    
    private Locale detectLocale(String request) {
        return Locale.CHINA;
    }
    
    private RequestId generateRequestId() {
        return RequestId.generate();
    }
}
1
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

# 结构化并发增强

import java.util.concurrent.*;
import java.util.*;

public class EnhancedStructuredConcurrency {
    
    public CompletableFuture<List<String>> processBatch(List<String> items) {
        try (var scope = new StructuredTaskScope.ShutdownOnSuccess<List<String>>()) {
            
            List<Future<List<String>>> futures = items.stream()
                .map(item -> scope.fork(() -> processItem(item)))
                .toList();
            
            scope.join();
            
            // 收集所有成功的结果
            return CompletableFuture.completedFuture(
                futures.stream()
                    .filter(Future::isDone)
                    .filter(future -> !future.isCancelled())
                    .map(Future::resultNow)
                    .flatMap(List::stream)
                    .toList()
            );
        }
    }
    
    // 带超时的结构化并发
    public List<String> processWithTimeout(List<String> items, Duration timeout) {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            List<Future<String>> futures = items.stream()
                .map(item -> scope.fork(() -> processWithDelay(item)))
                .toList();
            
            // 带超时的等待
            scope.joinUntil(Instant.now().plus(timeout));
            
            return futures.stream()
                .filter(Future::isDone)
                .map(Future::resultNow)
                .toList();
        }
    }
    
    private List<String> processItem(String item) {
        // 模拟处理逻辑
        return List.of("processed_" + item);
    }
    
    private String processWithDelay(String item) {
        try {
            // 模拟耗时操作
            Thread.sleep(100);
            return "delayed_" + item;
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
1
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

核心特性

  • 模块化隐式声明类 (预览):为初学者提供了一种平滑的Java编程入门途径,使其在不需要理解为大型程序设计的语言特性的情况下编写其第一个程序。
  • 作用域值 (正式):允许在线程之间共享不可变数据,提高了项目的易用性、可理解性、性能和鲁棒性。

# 💡 升级建议和最佳实践

# 从 Java 8 升级到 Java 21 的步骤

# 阶段1:准备和评估

  1. 代码库分析

    # 使用工具分析兼容性
    jdeps --jdk-version 21 your-application.jar
    jdeprscan --release 21 your-application.jar
    
    1
    2
    3
  2. 依赖检查

    • 更新所有依赖到支持Java 11+的版本
    • 移除或替换已废弃的依赖

# 阶段2:升级到 Java 11 LTS

  1. 解决模块化问题

    // 添加module-info.java或使用自动模块
    module com.yourapp {
        requires java.base;
        requires java.sql;
        requires transitive com.fasterxml.jackson.databind;
        exports com.yourapp.api;
    }
    
    1
    2
    3
    4
    5
    6
    7
  2. 处理移除的API

# 阶段3:采用新特性(渐进式)

阶段3.1:语法改进

// 使用 var
var list = new ArrayList<String>();
var map = new HashMap<String, Integer>();

// 使用新的集合工厂方法
List<String> immutableList = List.of("a", "b", "c");
Set<Integer> immutableSet = Set.of(1, 2, 3);
Map<String, Integer> immutableMap = Map.of("a", 1, "b", 2);
1
2
3
4
5
6
7
8

阶段3.2:API改进

// 使用新的字符串方法
if (string.isBlank()) { /* ... */ }
String stripped = string.strip();
String repeated = "Java".repeat(3);

// 使用新的HTTP Client
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com"))
    .build();
1
2
3
4
5
6
7
8
9
10

阶段3.3:现代特性

// 使用记录类替代DTO
public record User(String name, String email, int age) {}

// 使用模式匹配
if (obj instanceof String s && s.length() > 5) {
    return s.toUpperCase();
}

// 使用文本块
String json = """
    {
        "name": "John",
        "age": 30
    }
    """;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 阶段4:性能优化

// 使用虚拟线程处理高并发
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    // 处理大量IO密集型任务
}

// 使用向量API优化数值计算
// (参见前面的Vector API示例)
1
2
3
4
5
6
7

# 升级检查清单

  • 测试所有第三方库的兼容性
  • 更新构建工具配置 (Maven/Gradle)
  • 配置CI/CD管道支持新版本
  • 更新Docker基础镜像
  • 性能基准测试
  • 安全扫描和漏洞检查
  • 团队培训和新特性学习

# 🎯 总结与趋势

从 Java 8 到 Java 21+ 的演进是革命性的,不仅仅是语法糖的堆积,而是:

  1. 并发模型的重大革新
    • 虚拟线程彻底改变高并发编程范式
    • 结构化并发简化错误处理和资源管理
  2. 性能优化的质的飞跃
    • Vector API充分利用现代CPU SIMD指令
    • 新一代GC算法(ZGC, Shenandoah)提供亚毫秒暂停
    • AOT编译和CDS提升启动速度
  3. 开发体验的巨大提升
    • 模式匹配让代码更简洁安全
    • 记录类消除样板代码
    • 文本块改善字符串处理
  4. 安全性和维护性的显著改进
    • 强封装内部API
    • 模块化系统解决依赖冲突
    • 现代加密算法支持