广告位联系
返回顶部
分享到

JDK26新特性超详细介绍

java 来源:互联网 作者:佚名 发布时间:2026-08-16 07:26:39 人浏览
摘要

JDK 26 于 2026 年 3 月发布,是 JDK 25(LTS)之后的第一个非 LTS 版本。 本版本共有 10 个 JEP,其中 5 个正式特性、4 个预览特性、1 个孵化特性。 JDK 26 在并发、网络、性能和安全方面均有重要改进

JDK 26 于 2026 年 3 月发布,是 JDK 25(LTS)之后的第一个非 LTS 版本。

本版本共有 10 个 JEP,其中 5 个正式特性、4 个预览特性、1 个孵化特性。

JDK 26 在并发、网络、性能和安全方面均有重要改进。

1. HTTP/3 Client HTTP/3 客户端

1.1 概述

JEP 517 — HTTP/3 Client(HTTP/3 客户端)。JDK 26 为 java.net.http.HttpClient 添加了 HTTP/3 协议支持,基于 QUIC 传输协议。

改进:

  • 原生支持 HTTP/3 协议(基于 QUIC/UDP)
  • 0-RTT 连接建立,大幅降低延迟
  • 多路复用无队头阻塞
  • 连接迁移(网络切换不断连)
  • 与现有 HttpClient API 完全兼容
  • 自动协商(HTTP/3 → HTTP/2 → HTTP/1.1 回退)

1.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

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

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

import java.net.http.*;

import java.net.URI;

import java.time.Duration;

 

// ============ 1. 基本 HTTP/3 请求 ============

 

// 创建支持 HTTP/3 的客户端

HttpClient client = HttpClient.newBuilder()

    .version(HttpClient.Version.HTTP_3)  // 优先使用 HTTP/3

    .connectTimeout(Duration.ofSeconds(10))

    .build();

 

// 发送 GET 请求

HttpRequest request = HttpRequest.newBuilder()

    .uri(URI.create("https://api.example.com/data"))

    .GET()

    .build();

 

HttpResponse<String> response = client.send(request,

    HttpResponse.BodyHandlers.ofString());

 

System.out.println("Status: " + response.statusCode());

System.out.println("Version: " + response.version());  // HTTP_3

System.out.println("Body: " + response.body());

 

// ============ 2. 异步 HTTP/3 请求 ============

 

HttpClient asyncClient = HttpClient.newBuilder()

    .version(HttpClient.Version.HTTP_3)

    .build();

 

asyncClient.sendAsync(request, HttpResponse.BodyHandlers.ofString())

    .thenApply(HttpResponse::body)

    .thenAccept(body -> System.out.println("Async response: " + body))

    .join();

 

// ============ 3. 协议版本回退 ============

 

// 设置 HTTP/3 优先,服务器不支持时自动回退

HttpClient fallbackClient = HttpClient.newBuilder()

    .version(HttpClient.Version.HTTP_3)  // 优先 HTTP/3

    // 如果服务器不支持 HTTP/3,自动回退到 HTTP/2 或 HTTP/1.1

    .build();

 

HttpResponse<String> resp = fallbackClient.send(request,

    HttpResponse.BodyHandlers.ofString());

 

// 检查实际使用的协议版本

System.out.println("Actual version: " + resp.version());

// 可能输出: HTTP_3, HTTP_2, 或 HTTP_1_1

 

// ============ 4. POST 请求 ============

 

String jsonBody = """

    {"name": "Alice", "age": 30}

    """;

 

HttpRequest postRequest = HttpRequest.newBuilder()

    .uri(URI.create("https://api.example.com/users"))

    .header("Content-Type", "application/json")

    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))

    .build();

 

HttpResponse<String> postResp = client.send(postRequest,

    HttpResponse.BodyHandlers.ofString());

System.out.println("Created: " + postResp.statusCode());  // 201

 

// ============ 5. 并发请求(HTTP/3 多路复用优势)============

 

// HTTP/3 的多路复用无队头阻塞,并发性能更优

List<URI> uris = List.of(

    URI.create("https://api.example.com/users/1"),

    URI.create("https://api.example.com/users/2"),

    URI.create("https://api.example.com/users/3"),

    URI.create("https://api.example.com/users/4"),

    URI.create("https://api.example.com/users/5")

);

 

// 所有请求在单个 QUIC 连接上多路复用

List<CompletableFuture<HttpResponse<String>>> futures = uris.stream()

    .map(uri -> HttpRequest.newBuilder(uri).GET().build())

    .map(req -> asyncClient.sendAsync(req, HttpResponse.BodyHandlers.ofString()))

    .toList();

 

// 等待所有响应

List<String> bodies = futures.stream()

    .map(CompletableFuture::join)

    .map(HttpResponse::body)

    .toList();

 

// ============ 6. 流式响应(大文件下载)============

 

HttpRequest downloadReq = HttpRequest.newBuilder()

    .uri(URI.create("https://cdn.example.com/large-file.zip"))

    .GET()

    .build();

 

HttpResponse<InputStream> streamResp = client.send(downloadReq,

    HttpResponse.BodyHandlers.ofInputStream());

 

try (InputStream is = streamResp.body();

     OutputStream os = Files.newOutputStream(Path.of("download.zip"))) {

    is.transferTo(os);

}

 

// ============ 7. 配置超时和重试 ============

 

HttpClient robustClient = HttpClient.newBuilder()

    .version(HttpClient.Version.HTTP_3)

    .connectTimeout(Duration.ofSeconds(5))

    .followRedirects(HttpClient.Redirect.NORMAL)

    .build();

 

HttpRequest timedReq = HttpRequest.newBuilder()

    .uri(URI.create("https://api.example.com/slow"))

    .timeout(Duration.ofSeconds(30))  // 请求级超时

    .GET()

    .build();

 

// ============ 8. HTTP/3 vs HTTP/2 对比 ============

 

// | 特性 | HTTP/2 | HTTP/3 |

// |------|--------|--------|

// | 传输层 | TCP | QUIC (UDP) |

// | 队头阻塞 | 有(TCP 层)| 无 |

// | 连接建立 | 1-2 RTT | 0-1 RTT |

// | 连接迁移 | 不支持 | 支持 |

// | 加密 | 可选 TLS | 强制 TLS 1.3 |

// | 多路复用 | 有(受 TCP 限制)| 有(无限制)|

 

// ============ 9. 与虚拟线程配合 ============

 

// HTTP/3 + 虚拟线程 = 超高并发网络客户端

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {

    List<Future<String>> results = new ArrayList<>();

 

    for (int i = 0; i < 10_000; i++) {

        final int id = i;

        results.add(executor.submit(() -> {

            HttpRequest req = HttpRequest.newBuilder()

                .uri(URI.create("https://api.example.com/items/" + id))

                .GET()

                .build();

            return client.send(req, HttpResponse.BodyHandlers.ofString()).body();

        }));

    }

 

    // 处理结果...

}

2. AOT Object Caching AOT 对象缓存

2.1 概述

JEP 516 — AOT Object Caching(AOT 对象缓存)。JDK 26 扩展了 JDK 24 引入的 AOT 机制,支持缓存对象(不仅是类),并兼容所有 GC。

改进:

  • 缓存应用启动时创建的对象(如配置、元数据)
  • 支持所有垃圾收集器(G1、ZGC、Shenandoah、Parallel)
  • 进一步缩短启动时间
  • 减少启动阶段的内存分配和 GC 压力

2.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

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

# ============ 1. 创建 AOT 缓存(训练运行)============

 

# 第一次运行:记录类加载和对象创建信息

java -XX:AOTMode=record -XX:AOTCache=app.aot -jar app.jar

 

# 应用正常运行,同时生成缓存文件

 

# ============ 2. 使用 AOT 缓存启动 ============

 

# 后续运行:从缓存恢复,跳过大量初始化

java -XX:AOTCache=app.aot -jar app.jar

 

# ============ 3. 与不同 GC 配合使用 ============

 

# G1 GC(默认)

java -XX:AOTCache=app.aot -jar app.jar

 

# ZGC

java -XX:+UseZGC -XX:AOTCache=app.aot -jar app.jar

 

# Shenandoah

java -XX:+UseShenandoahGC -XX:AOTCache=app.aot -jar app.jar

 

# Parallel GC

java -XX:+UseParallelGC -XX:AOTCache=app.aot -jar app.jar

 

# ============ 4. JDK 24 vs JDK 26 AOT 对比 ============

 

# JDK 24(JEP 483):

# - 只缓存类加载和链接信息

# - 只支持默认 GC 配置

 

# JDK 26(JEP 516):

# - 缓存类加载 + 对象实例

# - 支持所有 GC

# - 启动加速效果更显著

 

# ============ 5. 启动时间对比(典型 Spring Boot 应用)============

 

# 无优化:~3.5 秒

# CDS(JDK 13+):~2.8 秒

# AOT 类加载(JDK 24):~1.5 秒

# AOT 对象缓存(JDK 26):~0.8 秒

 

# ============ 6. 容器化部署 ============

 

# Dockerfile

FROM eclipse-temurin:26-jdk AS builder

COPY app.jar /app/app.jar

# 训练运行生成缓存

RUN java -XX:AOTMode=record -XX:AOTCache=/app/app.aot -jar /app/app.jar --init-only

 

FROM eclipse-temurin:26-jre

COPY --from=builder /app/app.jar /app/app.jar

COPY --from=builder /app/app.aot /app/app.aot

ENTRYPOINT ["java", "-XX:AOTCache=/app/app.aot", "-jar", "/app/app.jar"]

 

# ============ 7. 注意事项 ============

 

# - AOT 缓存与 JDK 版本绑定

# - 缓存文件包含应用状态信息(注意安全)

# - 动态生成的类/对象可能无法缓存

# - 缓存文件大小取决于应用复杂度

# - 建议在 CI/CD 中生成缓存

3. G1 GC Throughput Improvement G1 吞吐量提升

3.1 概述

JEP 522 — G1 GC Throughput Improvement(G1 GC 吞吐量提升)。JDK 26 通过减少同步开销(双卡表机制)显著提升了 G1 GC 的吞吐量。

改进:

  • 引入双卡表(Dual Card Table)机制
  • 减少 GC 屏障的同步开销
  • 提升多线程应用的 GC 吞吐量
  • 对高并发应用效果尤为显著
  • 无需任何配置,升级即生效

3.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

40

41

42

43

44

45

# ============ 1. 默认启用(无需配置)============

 

# JDK 26 中 G1 GC 自动使用优化后的实现

java -jar app.jar

 

# 显式指定 G1(默认就是 G1)

java -XX:+UseG1GC -jar app.jar

 

# ============ 2. 监控 G1 性能 ============

 

# GC 日志

java -XX:+UseG1GC -Xlog:gc*:file=gc.log:time,level,tags -jar app.jar

 

# 查看 GC 统计

java -XX:+UseG1GC -Xlog:gc+stats=info -jar app.jar

 

# ============ 3. 性能对比 ============

 

# JDK 25 G1 vs JDK 26 G1(高并发场景):

# - 吞吐量提升:5%-15%

# - GC 暂停时间:基本不变

# - 内存占用:基本不变

# - CPU 利用率:更高效

 

# ============ 4. 适用场景 ============

 

# 受益最大的场景:

# - 高并发 Web 服务(大量虚拟线程/平台线程)

# - 写密集型应用(频繁对象创建)

# - 大堆应用(> 8GB)

# - 多线程数据处理管道

 

# ============ 5. G1 常用调优参数(JDK 26)============

 

# 目标暂停时间

java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar app.jar

 

# 堆大小

java -XX:+UseG1GC -Xms4g -Xmx4g -jar app.jar

 

# 区域大小

java -XX:+UseG1GC -XX:G1HeapRegionSize=16m -jar app.jar

 

# 混合 GC 触发阈值

java -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=45 -jar app.jar

4. Final Field Integrity 终态字段完整性

4.1 概述

JEP 500 — Final Field Integrity(终态字段完整性)。JDK 26 加强了 final 字段的不可变性保证,通过反射修改 final 字段时会产生警告。

改进:

  • 通过反射修改 final 字段时产生运行时警告
  • 为未来完全禁止反射修改 final 字段做准备
  • 提升代码安全性和可预测性
  • 帮助发现潜在的并发安全问题

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

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

81

82

83

import java.lang.reflect.Field;

 

// ============ 1. 问题背景 ============

 

class Config {

    final String env = "production";

    final int maxRetries = 3;

}

 

// JDK 25 及之前:可以通过反射修改 final 字段(危险!)

Config cfg = new Config();

Field f = Config.class.getDeclaredField("env");

f.setAccessible(true);

f.set(cfg, "development");  // JDK 25: 静默成功

System.out.println(cfg.env);  // "development" — 破坏了不可变性!

 

// ============ 2. JDK 26 行为变化 ============

 

// JDK 26:反射修改 final 字段会产生警告

Config cfg2 = new Config();

Field f2 = Config.class.getDeclaredField("env");

f2.setAccessible(true);

f2.set(cfg2, "staging");

// 控制台输出警告:

// WARNING: Illegal reflective access to final field 'env' in class Config

// WARNING: This operation will be disallowed in a future release

 

System.out.println(cfg2.env);  // 行为可能不确定

 

// ============ 3. 正确的替代方案 ============

 

// 方案一:使用不可变设计(推荐)

record AppConfig(String env, int maxRetries) {}

 

AppConfig config = new AppConfig("production", 3);

// config.env() 永远不可变

 

// 方案二:使用 setter(如果确实需要可变)

class MutableConfig {

    private String env = "production";

 

    public String getEnv() { return env; }

    public void setEnv(String env) { this.env = env; }

}

 

// 方案三:使用 AtomicReference(并发安全的可变)

class ConcurrentConfig {

    private final AtomicReference<String> env =

        new AtomicReference<>("production");

 

    public String getEnv() { return env.get(); }

    public void setEnv(String newEnv) { env.set(newEnv); }

}

 

// ============ 4. 框架迁移指南 ============

 

// 许多序列化/反序列化框架依赖反射修改 final 字段

// JDK 26 中这些框架需要更新:

 

// 旧方式(框架内部):

// Field field = obj.getClass().getDeclaredField("id");

// field.setAccessible(true);

// field.set(obj, deserializedValue);  // JDK 26 产生警告

 

// 新方式(框架应使用):

// 1. 使用构造器注入(推荐)

// 2. 使用 VarHandle

// 3. 使用 MethodHandle

// 4. 使用 Unsafe(临时方案,最终也会被限制)

 

// ============ 5. 检测项目中的问题代码 ============

 

// 运行时添加参数检测所有反射修改 final 字段的位置:

// java -Djava.lang.reflect.finalField.warning=verbose -jar app.jar

 

// 编译时检查:

// javac -Xlint:all MyClass.java

 

// ============ 6. 时间线 ============

 

// JDK 26:反射修改 final 字段 → 产生警告

// 未来版本:反射修改 final 字段 → 抛出异常

// 建议:尽早迁移,不要依赖反射修改 final 字段

5. Remove Applet API 移除 Applet API

5.1 概述

JEP 504 — Remove the Applet API(移除 Applet API)。JDK 26 彻底移除了 java.applet 包中的所有类。

改进:

  • 移除 java.applet.Applet 类
  • 移除 java.applet.AppletContext 等接口
  • 清理历史遗留代码
  • Applet 在 JDK 17 中已标记为弃用(for removal)

5.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

// ============ 1. 已移除的类 ============

 

// 以下类在 JDK 26 中不再存在:

// - java.applet.Applet

// - java.applet.AppletContext

// - java.applet.AppletStub

// - java.applet.AudioClip

 

// 编译使用这些类的代码会报错:

// error: package java.applet does not exist

 

// ============ 2. 迁移方案 ============

 

// 如果有遗留 Applet 代码,迁移选择:

 

// 方案一:迁移到 Java Web Start(也已弃用)→ 桌面应用

// 方案二:迁移到 JavaFX 富客户端

// 方案三:迁移到 Web 技术(HTML5 + JavaScript)

// 方案四:迁移到服务端渲染 + REST API

 

// ============ 3. 检查依赖 ============

 

// 检查项目是否依赖 Applet API:

// grep -r "java.applet" src/

// grep -r "extends Applet" src/

// grep -r "import java.applet" src/

 

// 大多数现代项目不会受影响

// Applet 技术已被淘汰超过 10 年

6. Structured Concurrency 结构化并发(第六次预览)

6.1 概述

JEP 525 — Structured Concurrency(结构化并发,第六次预览)。JDK 26 为结构化并发添加了超时支持(Joiner 超时),进一步简化并发编程。

改进:

  • 新增 Joiner.onTimeout() — 超时后返回默认值
  • 新增 Joiner.anySuccessfulOrThrow() 超时变体
  • 更灵活的子任务生命周期管理
  • 经过 6 次预览迭代,API 趋于稳定

6.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

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

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

import java.util.concurrent.StructuredTaskScope;

import java.util.concurrent.StructuredTaskScope.Joiner;

import java.util.concurrent.StructuredTaskScope.Subtask;

 

// ============ 1. 基本并行聚合(与之前版本相同)============

 

record UserProfile(User user, List<Order> orders) {}

 

UserProfile fetchProfile(String userId) throws Exception {

    try (var scope = StructuredTaskScope.open(

            Joiner.<Object>allSuccessfulOrThrow())) {

 

        Subtask<User> user = scope.fork(() -> getUser(userId));

        Subtask<List<Order>> orders = scope.fork(() -> getOrders(userId));

 

        scope.join();

 

        return new UserProfile(user.get(), orders.get());

    }

}

 

// ============ 2. 新增:超时 Joiner ============

 

// 超时后返回默认值,而非抛异常

Response handleWithTimeout(String requestId) throws Exception {

    try (var scope = StructuredTaskScope.open(

            Joiner.anySuccessfulOrThrow(),

            builder -> builder.withTimeout(Duration.ofMillis(300)))) {

 

        scope.fork(() -> callPrimaryService(requestId));

        scope.fork(() -> callSecondaryService(requestId));

 

        scope.join();

 

        return scope.result();

    } catch (TimeoutException e) {

        return Response.fallback();  // 超时返回默认响应

    }

}

 

// ============ 3. 超时 + 默认值 Joiner ============

 

String fetchWithFallback(String url) throws Exception {

    try (var scope = StructuredTaskScope.open(

            Joiner.onTimeout(Duration.ofSeconds(2), () -> "cached-default"))) {

 

        scope.fork(() -> httpGet(url));

        scope.fork(() -> httpGetMirror(url));

 

        scope.join();

 

        return scope.result();  // 超时则返回 "cached-default"

    }

}

 

// ============ 4. 竞速模式(取最快结果)============

 

<T> T race(List<Callable<T>> tasks) throws Exception {

    try (var scope = StructuredTaskScope.open(

            Joiner.<T>anySuccessfulOrThrow())) {

 

        tasks.forEach(scope::fork);

        scope.join();

 

        return scope.result();

    }

}

 

// 使用:从多个 CDN 取最快的

String content = race(List.of(

    () -> fetchFromCDN1(path),

    () -> fetchFromCDN2(path),

    () -> fetchFromCDN3(path)

));

 

// ============ 5. 批量处理 + 超时 ============

 

List<Result> processBatch(List<Task> tasks) throws Exception {

    try (var scope = StructuredTaskScope.open(

            Joiner.allSuccessfulOrThrow(),

            builder -> builder.withTimeout(Duration.ofSeconds(30)))) {

 

        List<Subtask<Result>> subtasks = tasks.stream()

            .map(t -> scope.fork(() -> execute(t)))

            .toList();

 

        scope.join();

 

        return subtasks.stream()

            .map(Subtask::get)

            .toList();

    }

}

 

// ============ 6. 与虚拟线程配合 ============

 

// StructuredTaskScope 内部自动使用虚拟线程

// 可以轻松 fork 大量子任务

try (var scope = StructuredTaskScope.open(

        Joiner.allSuccessfulOrThrow())) {

 

    for (int i = 0; i < 10_000; i++) {

        final int id = i;

        scope.fork(() -> processItem(id));

    }

 

    scope.join();

}

 

// ============ 7. 错误处理策略 ============

 

// 策略一:全部成功或抛异常

Joiner.allSuccessfulOrThrow()

 

// 策略二:任一成功即返回

Joiner.anySuccessfulOrThrow()

 

// 策略三:超时返回默认值

Joiner.onTimeout(Duration.ofSeconds(5), () -> defaultValue)

 

// 策略四:自定义 Joiner

Joiner<Object> custom = Joiner.of(completedSubtasks -> {

    // 自定义完成逻辑

    return completedSubtasks.stream()

        .filter(s -> s.state() == Subtask.State.SUCCESS)

        .map(Subtask::get)

        .toList();

});

7. Primitive Types in Patterns 原始类型模式(第四次预览)

7.1 概述

JEP 530 — Primitive Types in Patterns(原始类型模式,第四次预览)。JDK 26 继续改进原始类型在模式匹配中的支持,接近最终定稿。

改进:

  • 经过 JDK 23(预览)→ JDK 24(第二次预览)→ JDK 25(第三次预览)→ JDK 26(第四次预览)
  • instanceof 和 switch 全面支持所有原始类型
  • 安全的窄化转换匹配
  • API 趋于稳定

7.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

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

// ============ 1. switch 匹配所有原始类型 ============

 

String format(Object value) {

    return switch (value) {

        case byte b -> "0x" + Integer.toHexString(b & 0xFF);

        case short s -> "short:" + s;

        case int i -> "int:" + i;

        case long l -> "long:" + l;

        case float f -> String.format("%.2f", f);

        case double d -> String.format("%.4f", d);

        case char c -> "'" + c + "'";

        case boolean b -> b ? "YES" : "NO";

        case String s -> "\"" + s + "\"";

        default -> "unknown";

    };

}

 

// ============ 2. 带守卫的模式 ============

 

String classifyPrice(Object price) {

    return switch (price) {

        case int p when p < 100 -> "BUDGET";

        case int p when p < 500 -> "MID-RANGE";

        case int p -> "PREMIUM";

        case double d when d < 100.0 -> "BUDGET";

        case double d -> "PREMIUM";

        default -> "UNKNOWN";

    };

}

 

// ============ 3. 与 Record Patterns 配合 ============

 

record SensorReading(String sensor, Object value, long timestamp) {}

 

void processReading(SensorReading reading) {

    switch (reading) {

        case SensorReading("temperature", double d, _) ->

            System.out.printf("Temp: %.1f°C%n", d);

        case SensorReading("pressure", int p, _) ->

            System.out.printf("Pressure: %d hPa%n", p);

        case SensorReading("active", boolean b, _) ->

            System.out.println("Active: " + b);

        default ->

            System.out.println("Unknown reading: " + reading.sensor());

    }

}

 

// ============ 4. 数值解析与分发 ============

 

void handleInput(Object input) {

    switch (input) {

        case int i -> handleInteger(i);

        case long l -> handleLong(l);

        case double d -> handleDouble(d);

        case boolean b -> handleBoolean(b);

        case char c -> handleChar(c);

        case String s -> handleString(s);

        case null -> handleNull();

        default -> handleUnknown(input);

    }

}

 

// ============ 5. 安全窄化 ============

 

void narrowDemo(Object obj) {

    switch (obj) {

        // long 值如果在 int 范围内,可以匹配 int 模式

        case int i -> System.out.println("int: " + i);

        case long l -> System.out.println("long only: " + l);

        default -> System.out.println("not a number");

    }

}

 

narrowDemo(42);            // int: 42

narrowDemo(42L);           // int: 42(在 int 范围内)

narrowDemo(5_000_000_000L); // long only: 5000000000

8. PEM Encoding API PEM 编码 API(第二次预览)

8.1 概述

JEP 524 — PEM Encoding of Cryptographic Objects(PEM 编码 API,第二次预览)。JDK 26 继续改进 PEM 编码/解码 API,支持将密码学对象与 PEM 格式互相转换。

改进:

  • 标准 API 进行 PEM 编码/解码
  • 支持公钥、私钥、证书等密码学对象
  • 替代手动 Base64 + 头尾标记的繁琐操作
  • 与现有 JCA 体系无缝集成

8.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

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

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

import java.security.*;

import java.security.spec.*;

import javax.crypto.*;

 

// ============ 1. 公钥编码为 PEM ============

 

// 生成 RSA 密钥对

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");

kpg.initialize(2048);

KeyPair keyPair = kpg.generateKeyPair();

 

// 编码公钥为 PEM 字符串

PEMEncoder encoder = PEMEncoder.of();

String publicKeyPEM = encoder.encodeToString(keyPair.getPublic());

System.out.println(publicKeyPEM);

// -----BEGIN PUBLIC KEY-----

// MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...

// -----END PUBLIC KEY-----

 

// ============ 2. 私钥编码为 PEM ============

 

String privateKeyPEM = encoder.encodeToString(keyPair.getPrivate());

System.out.println(privateKeyPEM);

// -----BEGIN PRIVATE KEY-----

// MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAo...

// -----END PRIVATE KEY-----

 

// ============ 3. 从 PEM 解码为密钥对象 ============

 

PEMDecoder decoder = PEMDecoder.of();

 

// 解码公钥

PublicKey restoredPublic = decoder.decode(publicKeyPEM);

System.out.println("Algorithm: " + restoredPublic.getAlgorithm());  // RSA

 

// 解码私钥

PrivateKey restoredPrivate = decoder.decode(privateKeyPEM);

 

// ============ 4. 从文件读取 PEM ============

 

// 读取 PEM 文件

String pemContent = Files.readString(Path.of("server.crt"));

PublicKey certKey = decoder.decode(pemContent);

 

// 读取私钥文件

String keyContent = Files.readString(Path.of("server.key"));

PrivateKey serverKey = decoder.decode(keyContent);

 

// ============ 5. 写入 PEM 文件 ============

 

// 保存公钥

Files.writeString(Path.of("public.pem"),

    encoder.encodeToString(keyPair.getPublic()));

 

// 保存私钥

Files.writeString(Path.of("private.pem"),

    encoder.encodeToString(keyPair.getPrivate()));

 

// ============ 6. EC 密钥的 PEM 编码 ============

 

KeyPairGenerator ecKpg = KeyPairGenerator.getInstance("EC");

ecKpg.initialize(new ECGenParameterSpec("secp256r1"));

KeyPair ecKeyPair = ecKpg.generateKeyPair();

 

String ecPublicPEM = encoder.encodeToString(ecKeyPair.getPublic());

String ecPrivatePEM = encoder.encodeToString(ecKeyPair.getPrivate());

 

// ============ 7. ML-KEM / ML-DSA 密钥的 PEM 编码 ============

 

// 抗量子密钥也可以编码为 PEM

KeyPairGenerator mlKpg = KeyPairGenerator.getInstance("ML-KEM");

mlKpg.initialize(new NamedParameterSpec("ML-KEM-768"));

KeyPair mlKeyPair = mlKpg.generateKeyPair();

 

String mlPublicPEM = encoder.encodeToString(mlKeyPair.getPublic());

String mlPrivatePEM = encoder.encodeToString(mlKeyPair.getPrivate());

 

// ============ 8. 证书 PEM 编码 ============

 

// X.509 证书编码

CertificateFactory cf = CertificateFactory.getInstance("X.509");

X509Certificate cert = (X509Certificate) cf.generateCertificate(

    Files.newInputStream(Path.of("ca.crt")));

 

String certPEM = encoder.encodeToString(cert);

// -----BEGIN CERTIFICATE-----

// MIIC...

// -----END CERTIFICATE-----

 

// ============ 9. 实际应用场景 — TLS 证书配置 ============

 

// 从 PEM 文件加载 TLS 证书和私钥

String certPem = Files.readString(Path.of("tls/server.crt"));

String keyPem = Files.readString(Path.of("tls/server.key"));

 

PublicKey tlsPublic = decoder.decode(certPem);

PrivateKey tlsPrivate = decoder.decode(keyPem);

 

// 用于配置 SSLContext

KeyStore ks = KeyStore.getInstance("PKCS12");

ks.load(null, null);

ks.setKeyEntry("server", tlsPrivate, "changeit".toCharArray(),

    new java.security.cert.Certificate[]{(java.security.cert.Certificate) decoder.decode(certPem)});

 

// ============ 10. 与手动 Base64 方式对比 ============

 

// 传统手动方式(繁琐且易错):

String manualPem = "-----BEGIN PUBLIC KEY-----\n" +

    Base64.getMimeEncoder(64, "\n".getBytes())

        .encodeToString(keyPair.getPublic().getEncoded()) +

    "\n-----END PUBLIC KEY-----\n";

 

// JDK 26 PEM API(简洁安全):

String apiPem = PEMEncoder.of().encodeToString(keyPair.getPublic());

9. Lazy Constants 延迟常量(第二次预览)

9.1 概述

JEP 526 — Lazy Constants(延迟常量,第二次预览)。JDK 26 引入 LazyConstant API,提供线程安全的延迟初始化机制,替代 static final 急切初始化和双重检查锁定模式。

改进:

  • 线程安全的延迟初始化(无需 synchronized)
  • 值只计算一次,后续访问零开销
  • 替代双重检查锁定(DCL)反模式
  • 替代 static final 急切初始化(加速启动)
  • JVM 可以内联优化,性能等同直接字段访问

9.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

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

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

import java.lang.LazyConstant;

 

// ============ 1. 基本用法 ============

 

// 延迟初始化一个昂贵的对象

private final LazyConstant<DatabaseConnection> dbConnection =

    LazyConstant.of(() -> DatabaseConnection.create("jdbc:mysql://localhost/app"));

 

// 第一次访问时初始化

void query() {

    DatabaseConnection conn = dbConnection.get();  // 首次调用触发初始化

    conn.execute("SELECT ...");

}

 

// 后续访问直接返回缓存值(零开销)

void anotherQuery() {

    DatabaseConnection conn = dbConnection.get();  // 直接返回,无同步开销

    conn.execute("SELECT ...");

}

 

// ============ 2. 替代 static final 急切初始化 ============

 

// 传统方式:类加载时就初始化(拖慢启动)

class AppContext {

    // 即使不使用也会初始化

    private static final Logger LOGGER = Logger.create(AppContext.class);

    private static final Config CONFIG = Config.load();

    private static final MetricsRegistry METRICS = new MetricsRegistry();

}

 

// JDK 26 方式:按需初始化(加速启动)

class AppContext {

    private static final LazyConstant<Logger> LOGGER =

        LazyConstant.of(() -> Logger.create(AppContext.class));

    private static final LazyConstant<Config> CONFIG =

        LazyConstant.of(() -> Config.load());

    private static final LazyConstant<MetricsRegistry> METRICS =

        LazyConstant.of(() -> new MetricsRegistry());

 

    void handleRequest() {

        // 只有实际使用时才初始化

        LOGGER.get().info("Processing request");

        Config cfg = CONFIG.get();

    }

}

 

// ============ 3. 替代双重检查锁定(DCL)============

 

// 传统 DCL 模式(复杂且易错)

class Singleton {

    private static volatile Singleton instance;

 

    public static Singleton getInstance() {

        if (instance == null) {

            synchronized (Singleton.class) {

                if (instance == null) {

                    instance = new Singleton();

                }

            }

        }

        return instance;

    }

}

 

// JDK 26 LazyConstant(简洁安全)

class Singleton {

    private static final LazyConstant<Singleton> INSTANCE =

        LazyConstant.of(Singleton::new);

 

    public static Singleton getInstance() {

        return INSTANCE.get();

    }

}

 

// ============ 4. 替代 Holder 模式 ============

 

// 传统 Holder 模式

class ExpensiveService {

    private static class Holder {

        static final ExpensiveService INSTANCE = new ExpensiveService();

    }

    public static ExpensiveService getInstance() {

        return Holder.INSTANCE;

    }

}

 

// JDK 26 LazyConstant

class ExpensiveService {

    private static final LazyConstant<ExpensiveService> INSTANCE =

        LazyConstant.of(ExpensiveService::new);

 

    public static ExpensiveService getInstance() {

        return INSTANCE.get();

    }

}

 

// ============ 5. 实例级延迟初始化 ============

 

class OrderController {

    // 每个实例独立延迟初始化

    private final LazyConstant<Logger> logger =

        LazyConstant.of(() -> Logger.create(OrderController.class));

    private final LazyConstant<OrderValidator> validator =

        LazyConstant.of(() -> new OrderValidator(loadRules()));

 

    void handleOrder(Order order) {

        logger.get().debug("Processing order: " + order.id());

        validator.get().validate(order);

    }

}

 

// ============ 6. 条件性初始化 ============

 

class FeatureFlags {

    private final LazyConstant<Map<String, Boolean>> flags =

        LazyConstant.of(() -> {

            // 只在第一次访问时从远程加载

            return remoteConfigService.fetchFlags();

        });

 

    boolean isEnabled(String feature) {

        return flags.get().getOrDefault(feature, false);

    }

}

 

// ============ 7. 与虚拟线程配合 ============

 

// LazyConstant 在虚拟线程环境中同样安全高效

class RequestHandler {

    private final LazyConstant<HeavyResource> resource =

        LazyConstant.of(() -> HeavyResource.initialize());

 

    void handle() {

        // 多个虚拟线程并发调用 get()

        // 只有一个线程执行初始化,其他等待

        HeavyResource r = resource.get();

        r.process();

    }

}

 

// ============ 8. 性能特点 ============

 

// | 方式 | 线程安全 | 初始化后开销 | 代码复杂度 |

// |------|----------|-------------|-----------|

// | static final | 是 | 零 | 低 |

// | synchronized | 是 | 每次加锁 | 中 |

// | DCL | 是 | volatile 读 | 高 |

// | Holder | 是 | 零 | 中 |

// | LazyConstant | 是 | 零(JVM 内联)| 低 |

 

// LazyConstant 的优势:

// - 延迟初始化(不拖慢启动)

// - 初始化后零开销(JVM 可内联)

// - 代码简洁(一行声明)

// - 线程安全(无需手动同步)

 

// ============ 9. 注意事项 ============

 

// - LazyConstant 是不可变的(一旦设置不能更改)

// - 初始化函数不应有副作用(或确保幂等)

// - 如果初始化抛异常,后续 get() 会重新尝试

// - 不适合需要重新初始化的场景(用 AtomicReference)

// - 编译运行需要启用预览:

//   javac --enable-preview --source 26 App.java

//   java --enable-preview App

10. Vector API 向量 API(第十一次孵化)

10.1 概述

JEP 529 — Vector API(向量 API,第十一次孵化)。JDK 26 继续孵化向量 API,等待 Project Valhalla 值类型支持后正式标准化。

10.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

import jdk.incubator.vector.*;

 

static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_256;

 

// 向量加法

void add(float[] a, float[] b, float[] c) {

    int i = 0;

    for (; i < SPECIES.loopBound(a.length); i += SPECIES.length()) {

        FloatVector va = FloatVector.fromArray(SPECIES, a, i);

        FloatVector vb = FloatVector.fromArray(SPECIES, b, i);

        va.add(vb).intoArray(c, i);

    }

    for (; i < a.length; i++) c[i] = a[i] + b[i];

}

 

// 点积

float dot(float[] a, float[] b) {

    FloatVector sum = FloatVector.zero(SPECIES);

    int i = 0;

    for (; i < SPECIES.loopBound(a.length); i += SPECIES.length()) {

        sum = FloatVector.fromArray(SPECIES, a, i)

            .fma(FloatVector.fromArray(SPECIES, b, i), sum);

    }

    float r = sum.reduceLanes(VectorOperators.ADD);

    for (; i < a.length; i++) r += a[i] * b[i];

    return r;

}

 

// 编译: javac --add-modules jdk.incubator.vector VecDemo.java

// 运行: java --add-modules jdk.incubator.vector VecDemo

11. JDK 26 特性总览表

序号 特性 JEP 类型 状态 重要性
1 HTTP/3 Client JEP 517 网络 正式 ★★★★★
2 AOT Object Caching JEP 516 性能 正式 ★★★★★
3 G1 GC Throughput Improvement JEP 522 GC 正式 ★★★★☆
4 Final Field Integrity JEP 500 安全 正式 ★★★★☆
5 Remove Applet API JEP 504 清理 正式 ★★☆☆☆
6 Structured Concurrency(超时 Joiner) JEP 525 并发 第六次预览 ★★★★★
7 Primitive Types in Patterns JEP 530 语言 第四次预览 ★★★★★
8 PEM Encoding API JEP 524 安全 第二次预览 ★★★★☆
9 Lazy Constants JEP 526 API 第二次预览 ★★★★★
10 Vector API JEP 529 API 第十一次孵化 ★★★☆☆

附录:预览特性状态追踪

特性 JDK 23 JDK 24 JDK 25 JDK 26
Structured Concurrency 第三次预览 第四次预览 第五次预览 第六次预览
Primitive Types in Patterns 预览 第二次预览 第三次预览 第四次预览
PEM Encoding API 预览 第二次预览
Lazy Constants (Stable Values) 预览 第二次预览
Vector API 第八次孵化 第九次孵化 第十次孵化 第十一次孵化
Stream Gatherers 第二次预览 正式
Class-File API 第二次预览 正式
Scoped Values 第三次预览 第四次预览 正式
Module Import Declarations 预览 第二次预览 正式
Simple Source Files 第三次预览 第四次预览 正式
Flexible Constructor Bodies 第二次预览 第三次预览 正式
KDF API 预览 正式

附录:JDK 26 与其他版本的关系

项目 说明
发布日期 2026年3月
版本类型 非 LTS(短期支持)
前一个版本 JDK 25(LTS,2025年9月)
下一个版本 JDK 27(2026年9月)
下一个 LTS JDK 29(预计 2027年9月)
主要意义 后 LTS 创新版本,引入 HTTP/3 和延迟常量等重要特性

JDK 26 的关键贡献:

  1. HTTP/3 原生支持 — Java 网络编程进入 QUIC 时代
  2. AOT 对象缓存 — 启动加速从类级别扩展到对象级别
  3. G1 GC 吞吐量提升 — 双卡表机制减少同步开销
  4. Final 字段完整性 — 加强不可变性保证
  5. Lazy Constants — 优雅的延迟初始化方案
  6. Structured Concurrency 超时 — 更实用的并发超时处理
  7. PEM Encoding API — 密码学对象编码标准化
  8. 移除 Applet API — 清理历史遗留

总结:JDK 26 是 JDK 25 LTS 之后的第一个创新版本,在多个方向带来重要突破。HTTP/3 客户端 让 Java 原生支持基于 QUIC 的现代网络协议;AOT 对象缓存 将启动加速从类加载扩展到对象级别;Lazy Constants 提供了优雅的延迟初始化方案,替代了复杂的 DCL 和 Holder 模式;G1 GC 吞吐量提升 让默认 GC 在高并发场景下表现更好;Final 字段完整性 加强了 Java 的不可变性保证。结构化并发和原始类型模式等预览特性继续演进,为后续版本定稿做准备


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计