JDK 26 新特性

共 36 题
📑 题目列表 36 题
#
★★★

1. JDK 26 与 Spring Boot 4.1.0 的兼容

JDK 26 与 Spring Boot 4.1.0 的兼容性如何?

  • JDK 26 的发布状态与 Spring Boot 4.1.0 的支持范围
  • Java 17+ 基线的向上兼容
  • 升级到 JDK 26 的影响与注意事项

JDK 26 是 2026 年 3 月发布的非 LTS 版本,Spring Boot 4.1.0 在其支持范围内通常可运行于 JDK 26。由于 Spring Boot 4.x 的 Java 17 基线,其编译字节码为 Java 17 版本,可在 JDK 26 上向下兼容执行。不过 JDK 26 引入了若干行为变化(如 final 字段完整性 JEP 500、HTTP/3、移除 Applet API 等),Spring Boot 4.1.0 应用应验证框架初始化、反射、序列化与字节码增强工具在 JDK 26 下的兼容性。生产环境通常建议使用 LTS(JDK 25),JDK 26 用于评估与特性尝鲜。

非 LTS 版本(每 6 个月发布)的兼容性依赖官方认证与社区验证。JDK 26 的行为变化(final 字段完整性、GC 默认值)可能影响 Spring Boot 的代理与 AOT 机制,升级前需验证。

#
★★

2. AOT 缓存归档失效的触发条件、可观测信号与安全回退路径

AOT 缓存归档失效的触发条件、可观测信号与安全回退路径是什么?

  • AOT 缓存失效的触发条件
  • 可观测信号(日志、JFR)
  • 安全回退路径

AOT 缓存归档失效的触发条件包括:类路径或模块路径变化、JDK 版本变更、CPU 架构不匹配、类加载顺序变化、以及方法画像(profile)偏斜导致缓存命中率低。可观测信号包括:-Xlog:aot* 日志中的缓存未命中(cache miss)记录、JFR 的 AOT 缓存相关事件、以及启动时段的类加载耗时异常。安全回退路径是:当缓存失效或未命中时,JVM 自动忽略 AOT 缓存并回退到解释执行 + JIT 编译,保证应用功能正确,只是启动性能降低。生产环境应通过监控缓存命中率与启动时间,在缓存失效时重新生成归档。

AOT 缓存是"性能优化而非正确性依赖",因此失效必须安全回退。正确性由 CDS 的类加载验证与 JVM 的运行时保证兜底,可观测信号用于及时识别失效并重新训练。

#
★★

3. JEP 516 AOT 对象缓存与不同垃圾收集器协作的启动收益验证

JEP 516 的 AOT 对象缓存如何与不同垃圾收集器协作,并验证启动收益?

  • JEP 516 的 AOT 对象缓存
  • 与 GC 的协作
  • 启动收益验证方法

JEP 516(JDK 26)提供 AOT 对象缓存,将应用启动时高频创建的对象(如配置、元数据、字符串常量)预创建并缓存,启动时直接加载,减少对象分配与类初始化开销。它与不同垃圾收集器协作:AOT 对象缓存的对象在 GC 中作为"已分配"对象处理,G1、ZGC、Shenandoah 均需支持从缓存快速放置对象。启动收益验证通过对比开启/关闭 AOT 缓存时的启动时间(到"应用就绪"的毫秒数)、对象分配量与类加载耗时,并配合 JFR 的启动事件与 GC 日志确认缓存带来的分配减少。

AOT 对象缓存的核心收益是减少启动期对象图构建成本。收益验证需控制变量(同 GC、同参数),用启动时间与分配量两个指标衡量,并确认 GC 能正确管理缓存对象。

#
★★

4. JEP 522 为什么用双 Card Table 和原子交换减少 G1 应用线程写屏障与并发 Refinement 线程之间的同步

JEP 522 为什么用双 Card Table 和原子交换减少 G1 应用线程写屏障与并发 Refinement 线程之间的同步?

  • G1 的写屏障与 Card Table
  • 应用线程与 Refinement 线程的竞争
  • 双 Card Table 与原子交换

G1 使用 Card Table 记录对象引用变更,应用线程写对象引用时在其写屏障中标记对应的 Card,Refinement 线程并发处理这些 Card 以更新 RSet。传统实现中,写屏障与 Refinement 线程对 Card Table 的读取/清理存在竞争,需要同步(如锁或 CAS)导致吞吐下降。JEP 522 采用双 Card Table:应用线程写屏障只写入一个表,Refinement 线程通过原子交换(atomic swap)切换活动表,实现"无等待"的写屏障,消除写屏障与 Refinement 之间的直接竞争,从而减少同步、提升 G1 吞吐量。

双缓冲(double buffering)是经典的并发解耦手法:写方与读方各用独立表,通过原子交换避免锁竞争。这让写屏障极端轻量,减轻 G1 在大量引用写入场景下的同步开销。

#
★★

5. G1 同步削减后如何区分吞吐收益与暂停时间分布变化

G1 同步削减后,如何区分吞吐收益与暂停时间分布变化?

  • 吞吐与暂停时间的指标
  • 对照实验设计
  • 统计分析方法

区分吞吐收益与暂停时间分布变化需分别测量:吞吐量用每秒完成的操作数(OPS)或 GC 时间占比衡量;暂停时间用 GC pause 的 P50/P95/P99 与分布(直方图)衡量。JEP 522 通过减少同步提升的是应用线程吞吐,但可能改变 GC 暂停的触发时机与分布。应设计对照实验:同一 workload、同一堆、同一 GC 参数,仅开启/关闭 JEP 522 优化(或对比新旧 JDK),收集 OPS 与暂停分布,用统计检验(如均值、分位数、置信区间)判断差异是否显著,并区分"吞吐提升"与"暂停更集中但更短"两类效果。

吞吐与暂停是正交指标,G1 优化可能同时或单独影响两者。只有同时测量两个维度并做统计对照,才能归因收益来源,避免把暂停分布变化误判为吞吐提升。

#
★★

6. JDK 26 容器镜像灰度时 CDS/AOT 归档与运行时构建一致性校验

JDK 26 容器镜像灰度时,如何校验 CDS/AOT 归档与运行时的构建一致性?

  • 容器镜像与 CDS/AOT 归档
  • 构建一致性的校验
  • 灰度发布的风险

容器镜像灰度发布时,CDS/AOT 归档需与运行时保持一致,否则缓存失效或报错。校验内容包括:JDK 版本(构建号)、类路径哈希、模块哈希、CPU 架构、AOT 缓存 UUID 等。可观测信号是 -Xlog:cds,aot 的日志与缓存加载失败错误。实践中在镜像构建时生成归档并记录其指纹(hash),运行时校验镜像指纹与归档指纹一致;在现代容器中,将多个目标架构的归档合并到镜像(如 CDS 的 archive 按 arch 选择),或构建时生成与运行时公共类路径一致的归档。灰度时先在小流量节点验证归档加载成功(无 miss、无报错)再全量。

容器化下 CDS/AOT 的一致性风险来自类路径与架构差异。构建时生成、运行时校验指纹、灰度渐进验证,是平衡收益与安全的做法。

#
★★

7. JEP 500 对反射、框架注入和反序列化写入 final 字段的迁移影响

JEP 500 对反射、框架注入和反序列化写入 final 字段的迁移影响是什么?

  • JEP 500 的 final 字段完整性
  • 反射与框架注入
  • 反序列化写入 final 字段

JEP 500(Prepare to Make Final Mean Final)逐步限制对 final 字段的修改:通过反射、Unsafe、框架注入(如 DI 框架、mock 框架)或反序列化绕过 final 语义写入 final 字段的行为将受限并引发警告或错误。JDK 26 中,对 final 字段的非法写入会抛警告(-XX:+UnsafeFinalFieldAccess 等诊断),未来将变为禁止。迁移影响:依赖反射或 Unsafe 写入 final 字段的框架(如某些 ORM、mock、序列化库)需改用 VarHandle、构造器注入、或 byterun 的合法路径。应用代码应避免反射修改 final 字段,改用构造器或初始化方法。

这是 JDK"integrity-by-default"路线的一部分,让 final 真正表示不可变,提升安全与可预测性。框架迁移到 VarHandle 或构造器注入,避免破坏 final 语义。

#
★★

8. JEP 522 通过减少同步提升 G1 吞吐量时应使用的对照指标

JEP 522 通过减少同步提升 G1 吞吐量时,应使用哪些对照指标?

  • 吞吐量指标
  • 对照实验
  • 同步减少的量化

评估 JEP 522 的 G1 吞吐提升,对照指标包括:应用吞吐量(OPS/每秒请求数)、GC 时间占比(% of time in GC)、写屏障开销(通过 JFR 或基准测试)、以及 Refinement 线程的 CPU 占用。应在同一 workload 下对比开启/关闭优化(或新旧 JDK)的 OPS 与 GC 时间占比,并观察写屏障相关的事件(如 JFR 的 SATB 或 dirty card 统计)是否减少。同步削减的直接证明是写屏障与 Refinement 竞争导致的等待时间下降,间接证明是吞吐提升。

对照指标需覆盖"直接效果"(同步减少)与"最终效果"(吞吐提升)。用 OPS 与 GC 时间占比衡量吞吐,用写屏障/Refinement 统计衡量同步削减,构成完整的证据链。

#
★★

9. final 字段完整性限制对 JNI、Unsafe 和深反射工具链的影响

final 字段完整性限制对 JNI、Unsafe 和深反射工具链的影响是什么?

  • final 字段完整性限制
  • JNI 与 Unsafe 的字段访问
  • 深反射工具链的迁移

final 字段完整性限制(JEP 500)影响 JNI、Unsafe 和深反射工具链:它们过去可绕过 final 语义修改 final 字段,现在这些操作被限制并可能告警。JNI 通过 Get/SetField 修改 final 字段、Unsafe 通过 putObject 修改 final 字段、深反射通过 Field.set 修改 final 字段的行为都将受影响。受影响工具链需迁移到 VarHandle(不区分 final 语义的合法写入)、构造器注入、或重新设计初始化流程。JDK 26 提供诊断选项(如 -XX:+UnsafeFinalFieldAccess)与 JFR 事件来盘点依赖,帮助迁移。

JNI/Unsafe/反射是"绕过语言约束"的通道,final 完整性限制统一收敛这些通道,向"final 即不可变"的模型靠拢。迁移的核心是找到合法的初始化路径(构造器、VarHandle)。

#
★★

10. 原始类型模式中的数值精确性检查、守卫条件和装箱差异

原始类型模式中的数值精确性检查、守卫条件和装箱差异是什么?

  • 原始类型模式(primitive patterns)
  • 数值精确性检查
  • 守卫条件与装箱

原始类型模式(JEP 530,JDK 26 第四次预览)允许在 instanceof 与 switch 中匹配原始类型(如 int、long、byte)。数值精确性检查用于处理类型转换的精度问题:如把一个 long 匹配到 int 模式时,需检查值是否在 int 范围内,超范围则视为不匹配。守卫条件(when 子句)可附加在模式上,进一步限定匹配。装箱差异在于:原始类型模式避免装箱,直接在原始类型上比较,性能优于先装箱再匹配;但原始与包装类型混用时需注意语义(如 null 的匹配)。

原始类型模式的价值是避免装箱开销并支持精度受限的匹配。精确性检查保证窄类型模式不会静默丢失精度,守卫条件提供更细粒度控制,装箱差异决定性能与 null 语义。

#
★★

11. 结构化并发预览 API 再次演进时如何隔离业务代码与孵化接口

结构化并发预览 API 再次演进时,如何隔离业务代码与孵化接口?

  • 结构化并发 API 的预览演进
  • 隔离业务代码与孵化接口
  • 预览依赖治理

结构化并发(StructuredTaskScope)在 JDK 26 的 JEP 525 第六次预览,API 仍可能变化。隔离业务代码与孵化接口的方法是:将结构化并发 API 的调用封装在适配层/门面(facade)中,业务代码只依赖自定义接口,不直接依赖 java.util.concurrent.StructuredTaskScope 的预览实现;通过 --enable-preview 编译的模块单独隔离,避免预览 API 泄漏到公共 API;用依赖抽象(如 ExecutorService 风格回调)屏蔽 API 变化。这样当预览 API 演进或转正时,只需修改适配层。

预览 API 在多次预览中可能改名与改签名,直接依赖会带来迁移成本。适配层隔离 + 编译期 --enable-preview 隔离,是预览依赖治理的标准做法。

#
★★

12. JDK 26 与 Spring AI 2.0.0(Java 17+ 基线)

JDK 26 与 Spring AI 2.0.0 的兼容性如何?

  • Spring AI 2.0.0 的 Java 基线
  • 与 JDK 26 的兼容
  • AI 生态的 Java 要求

Spring AI 2.0.0 与 Spring Boot 4.x 对齐,采用 Java 17+ 基线,因此可在 JDK 26 上运行。Spring AI 提供大模型、向量数据库、Agent 等 AI 集成能力,其运行时依赖 Java 的并发、HTTP 客户端与序列化能力。JDK 26 的 HTTP/3(JEP 517)、虚拟线程与结构化并发可为 AI 应用(如流式调用、并行 Agent 编排)提供支持。兼容性需验证 Spring AI 2.0.0 依赖的 HTTP 库、JSON 库与 AI 客户端在 JDK 26 下的行为。

Spring AI 2.0.0 与 Spring Boot 4 同基线,JDK 26 的非 LTS 状态与行为变化(final 完整性、HTTP/3)需验证。AI 应用的高并发与流式特性恰好受益于虚拟线程。

#
★★

13. JDK 26 与 Spring Modulith 2.1.0 的兼容

JDK 26 与 Spring Modulith 2.1.0 的兼容性如何?

  • Spring Modulith 的模块化支持
  • 与 JDK 26 的兼容
  • 事件与模块边界

Spring Modulith 2.1.0 与 Spring Boot 4.x 对齐,支持 Java 17+,可在 JDK 26 上运行。Spring Modulith 提供应用模块化框架(模块边界、事件发布、模块 API 文档),其事件机制与模块扫描在 JDK 26 下运行需验证反射与字节码(如 final 字段完整性、类扫描)不受影响。JDK 26 的 Scoped Values 与结构化并发可用于模块事件的上下文传递,与 Modulith 的事件模型配合。

Modulith 依赖反射与类路径扫描来识别模块边界,JDK 26 的 final 完整性限制可能影响其对 final 字段的注入,需验证。兼容性重点是模块隔离与事件传递在 JDK 26 下的正确性。

#
★★

14. JEP 486(JDK 24)永久禁用 Security Manager 后,JDK 26 中依赖 SecurityManager 权限模型的存量代码如何迁移

JEP 486 在 JDK 24 永久禁用 Security Manager 后,JDK 26 中依赖 SecurityManager 权限模型的存量代码如何迁移?

  • Security Manager 的永久禁用
  • 存量代码的迁移路径
  • 替代权限模型

JEP 486 在 JDK 24 永久禁用 Security Manager,JDK 26 中任何调用 SecurityManager 相关 API 的代码都会抛 UnsupportedOperationException。存量代码迁移路径包括:移除自定义 SecurityManager 与 AccessController.doPrivileged 调用;改用语言级与模块级约束(如 JEP 500 的 final 字段完整性、模块封装、--illegal-access 控制);对需要权限控制的场景重新设计(如使用专用框架的权限模型、容器安全、或 JNI 的受限访问)。依赖 SecurityManager 的框架(如某些应用服务器、Applet 时代遗留代码)需重写。

Security Manager 的移除是"integrity-by-default"与安全简化的一部分。迁移的核心是识别依赖 SecurityManager 的调用点,替换为模块化、语言级或框架级约束,消除对全局权限检查的依赖。

#

15. Lazy Constants 与类初始化锁、holder idiom 和 Stable Values 的取舍

Lazy Constants 与类初始化锁、holder idiom 和 Stable Values 的取舍是什么?

  • Lazy Constants 的延迟初始化
  • holder idiom 与类初始化锁
  • 与 Stable Values 的关系

Lazy Constants(JEP 526,JDK 26 第二次预览,由 JEP 502 Stable Values 重命名)允许声明延迟初始化的常量。传统延迟初始化单例用 holder idiom(static 嵌套类持有实例),依赖类初始化锁保证线程安全,但会触发类初始化。Lazy Constants 直接在 JVM 层面支持"首次访问时初始化一次",避免 holder idiom 的类初始化成本与锁竞争。与 Stable Values 的关系:Stable Values 是更早的命名,Lazy Constants 是其演进,语义更聚焦于"惰性常量"。取舍上,Lazy Constants 更简单、无需额外类,但初始化表达式受限。

holder idiom 是实现延迟单例的经典手段,但引入额外类与初始化顺序约束。Lazy Constants 把"惰性单次初始化"下沉到 JVM,减少样板代码与锁竞争,代价是初始化表达式受限。

#

16. HTTP/3 的 QUIC 握手、证书验证与企业代理不兼容时如何诊断

HTTP/3 的 QUIC 握手、证书验证与企业代理不兼容时如何诊断?

  • QUIC 握手与 TLS 1.3
  • 证书验证
  • 企业代理与 UDP 阻断

HTTP/3 基于 QUIC(UDP + TLS 1.3),QUIC 握手内嵌 TLS 1.3 握手。诊断 QUIC 握手失败需检查:UDP 端口 443 是否被防火墙/企业代理阻断(很多企业代理只转发 TCP,不转发 UDP);TLS 1.3 证书验证是否通过(证书链、主机名验证);以及 0-RTT 重放导致的握手拒绝。企业代理不兼容时,QUIC 握手会超时,可回退到 HTTP/2(HTTPS)。诊断手段包括:抓包(tcpdump/Wireshark 看 QUIC 包)、-Xlog 或 HttpClient 的日志、以及检查网络连通性(UDP 可达性)。

HTTP/3 最主要的兼容障碍是网络层对 UDP 的阻断与中间设备对 QUIC 的识别。诊断需区分"协议层失败"(握手、证书)与"网络层失败"(UDP 阻断),并通过回退策略保障可用性。

#

17. JDK 26 的 GC 演进(JEP 522,G1 降低同步开销)

JDK 26 中 G1 的默认地位与 JEP 522(降低同步开销)的内容是什么?

  • JEP 522 的目标与手段(减少同步、提升吞吐)
  • G1 仍是默认 GC
  • 对应用的影响(无默认值变化)

JDK 26 中 G1 仍是默认 GC,没有"更换默认 GC"或"调整默认参数"的变更;与 GC 直接相关的 JEP 522(G1 GC: Improve Throughput by Reducing Synchronization)通过减少 G1 内部同步开销(如并发阶段与 RSet 维护的同步竞争)提升吞吐,不改变默认 GC 选择与默认参数,对应用透明。应用升级 JDK 26 后无需为 GC 默认值做特殊配置,只需照常验证暂停与吞吐。变化导致的暂停与吞吐差异,通过 -XX:+PrintGCDetails 或 -Xlog 观察。

JEP 522 的定位是"不改变默认行为、只降低同步开销"的吞吐优化;面试回答应强调 G1 保持默认、JEP 522 对应用透明,避免把"GC 演进"夸大为"默认 GC 变更"。

#

18. JDK 26 的编译器优化(C2 改进)

JDK 26 的 C2 编译器有哪些优化改进?

  • C2 的优化方向
  • 与向量化、AOT 的配合
  • 对性能的影响

JDK 26 的 C2 编译器改进包括:更好的方法内联与去内联启发式、增强的自动向量化(配合 Vector API)、更精准的逃逸分析、以及针对虚拟线程与锁的优化。C2 还与 AOT 缓存(JEP 516)配合,使 AOT 生成的代码与 C2 的后续优化衔接。C2 改进的目标是提升吞吐与降低延迟,尤其针对热点方法。

C2 是 JIT 的优化主力,其改进多体现在内联、向量化与逃逸分析。JDK 26 的 C2 与 AOT、Vector API 的协同,使纯 Java 高性能计算与云原生启动都受益。

#

19. JEP 500 Prepare to Make Final Mean Final 的语义变化

JEP 500 的语义变化是什么,"Prepare to Make Final Mean Final"是什么意思?

  • JEP 500 的语义
  • final 的真正含义
  • 对非法写入的处理

JEP 500(Prepare to Make Final Mean Final)的目标是让 final 字段真正不可变。当前版本中,通过反射、Unsafe、JNI 或反序列化仍可绕过 final 语义修改 final 字段,JEP 500 逐步限制这些行为:JDK 26 起对非法写入产生警告(诊断选项),未来版本将变为禁止(抛异常)。语义变化是"final 既不能被语言修改也不能被绕过修改",从而提升安全与可预测性。JEP 500 提供 -XX:+UnsafeFinalFieldAccess 等诊断与 JFR 事件来盘点依赖并迁移。

"Prepare" 表示这是渐进步骤:先警告、再禁止,给生态迁移时间。最终语义是 final 字段在构造完成后不可变更,任何绕过手段都失效。

#

20. JEP 517 HTTP/3 for the HTTP Client API 的协议升级

JEP 517 为 HttpClient 增加 HTTP/3 的协议升级是什么?

  • HTTP/3 与 QUIC
  • HttpClient 的协议支持
  • 升级路径

JEP 517(JDK 26)为 Java HttpClient 提供 HTTP/3 支持,基于 QUIC(UDP + TLS 1.3)。HTTP/3 相对 HTTP/2 的优势是多路复用无队头阻塞、更快的连接建立(0-RTT)、更好的连接迁移。JEP 517 允许 HttpClient 通过 Alt-Svc 升级或显式指定的 HTTP/3 URI 使用 HTTP/3,网络层使用 UDP。协议升级通过 HTTP/3 的扩展、Alt-Svc 通告或显式 URI 触发,并支持回退到 HTTP/2。

HTTP/3 是 HTTP 协议的演进,Java 通过 HttpClient 提供支持。升级路径需考虑发现机制(Alt-Svc 等)与回退策略,保证在不支持 QUIC 的网络下可用。

#

21. JEP 517 HTTP/3 客户端在连接迁移、0-RTT 与回退 HTTP/2 时的语义

JEP 517 HTTP/3 客户端在连接迁移、0-RTT 与回退 HTTP/2 时的语义是什么?

  • 连接迁移
  • 0-RTT 语义
  • 回退 HTTP/2

HTTP/3 客户端语义:连接迁移指 QUIC 连接 ID 可在网络变化(如 Wi-Fi 切蜂窝)时保持连接,不中断;0-RTT 允许客户端在 TLS 1.3 会话恢复时携带首包数据,减少往返,但存在重放风险(服务端可拒绝 0-RTT 数据导致重试);回退 HTTP/2 指当 UDP 不可达或 QUIC 握手失败时,客户端回退到 HTTP/2(HTTPS/TCP),保证可用性。语义上,连接迁移是透明的,0-RTT 需处理重放拒绝,回退降低延迟但牺牲 HTTP/3 收益。

这三个语义分别对应 QUIC 的健壮性、性能与兼容性。生产使用需理解 0-RTT 的重放语义与回退导致的延迟差异,以便正确诊断。

#

22. JEP 525 第六次预览结构化并发的 API 变化与预览依赖治理

JEP 525 第六次预览结构化并发的 API 变化与预览依赖治理是什么?

  • JEP 525 的 API 变化
  • 预览依赖治理
  • 第六次预览的状态

JEP 525(JDK 26)第六次预览结构化并发(StructuredTaskScope),API 在多次预览中持续演进(如方法签名、异常处理、Scope 的继承语义)。第六次预览意味着 API 接近稳定但仍有调整,尚未转正。预览依赖治理包括:将依赖结构化并发 API 的代码隔离在适配层,通过 --enable-preview 编译,避免在公共 API 暴露预览类型,并关注每次预览的迁移说明。转正后移除适配层即可。

六次预览反映结构化并发 API 设计的高标准与稳定性追求。治理策略是隔离 + 编译期控制,降低预览演进对业务代码的影响。

#

23. JDK 26 的 -Xlog 与 JFR 增强

JDK 26 对 -Xlog 与 JFR 做了哪些增强?

  • -Xlog 的日志增强
  • JFR 的新事件
  • 可观测性提升

JDK 26 增强 -Xlog 与 JFR:新增 HTTP/3(QUIC)、AOT 对象缓存、final 字段警告等日志标签与事件;JFR 增加结构化并发、虚拟线程调度、final 字段违规写入等事件;增强 JFR Streaming API 与 CPU-Time Profiling(JEP 509)。这些增强让生产环境对 HTTP/3 连接、AOT 缓存、并发与安全行为具备更细粒度可观测性。

可观测性随新特性扩展:每个新特性(HTTP/3、AOT、final 完整性)都配套日志与 JFR 事件,便于诊断与运维。JDK 26 的增强聚焦于新特性与安全行为的可观测。

#

24. JEP 524 PEM Encodings of Cryptographic Objects(2nd Preview,JDK 26)的 API 变化与安全编码场景

JEP 524 第二次预览 PEM 编码的 API 变化与安全编码场景是什么?

  • JEP 524 的 API 变化
  • 安全编码场景
  • 第二次预览状态

JEP 524(JDK 26)第二次预览 PEM 编码(PEM Encodings of Cryptographic Objects),在 JEP 470(JDK 25 第一次预览)基础上调整 API,如改进编码/解码的对象类型支持、错误处理与名称解析。安全编码场景包括:读写 PEM 格式的私钥、证书、证书链、CRL、密钥对,用于 TLS、签名、密钥交换的互操作。API 变化聚焦于更统一的编码接口与更清晰的错误类型。

二次预览基于社区的反馈优化 API。PEM 编码的安全场景强调正确处理密钥格式与错误(如损坏的 PEM、不支持的算法),统一 API 减少格式处理错误。

#

25. JDK 26 的网络 API 改进

JDK 26 的网络 API 有哪些改进?

  • HTTP/3 支持
  • 网络 API 的其他改进
  • 与虚拟线程的配合

JDK 26 的网络 API 改进核心是 JEP 517 的 HTTP/3 支持(基于 QUIC),此外还包括:HttpClient 的协议发现与回退增强、套接字与通道对虚拟线程的优化、以及网络相关诊断(如 QUIC 连接 ID)的增强。这些改进让 Java 网络编程在 HTTP/3、高并发与可观测性上更完善,并与虚拟线程的阻塞 I/O 挂起机制配合。

网络 API 的演进聚焦 HTTP/3 协议与虚拟线程集成。JDK 26 的网络改进提升了协议现代性、并发能力与可观测性。

#

26. JDK 26 预览特性编译、运行、测试与制品发布的 --enable-preview 管理

JDK 26 预览特性在编译、运行、测试与制品发布时如何管理 --enable-preview?

  • 编译与运行时的 --enable-preview
  • 测试与制品发布
  • 预览依赖治理

使用预览特性时,编译和运行都必须传递 --enable-preview(javac 与 java 需同时指定),且运行时的 Java 版本必须支持该预览特性。测试时,测试框架(如 JUnit)的测试类也要用 --enable-preview 编译并运行。制品发布时,预览特性依赖的字节码与运行环境需匹配,且预览特性可能在后续版本变化或移除,因此发布预览制品需记录所依赖的 JDK 版本与预览特性,并隔离预览依赖。团队应通过构建配置(如 Maven/Gradle 的 compilerArgs)统一管理 --enable-preview,避免手工遗漏。

--enable-preview 是预览特性的强制开关,编译与运行必须一致,否则链接错误或运行失败。制品发布需考虑预览特性的版本依赖与演进风险,故隔离与记录是关键。

#

27. JEP 485 Stream Gatherers(JDK 24 Final)

JEP 485 将 Stream Gatherers 定稿(Final)后,提供了什么能力?

  • Stream Gatherers 的概念
  • 自定义中间操作
  • 定稿状态

JEP 485(JDK 24)将 Stream Gatherers 定稿,为 Stream API 引入可自定义的中间操作(gatherer)。Gatherer 通过 Gatherer<Input, State, Output> 接口定义综合、投影、集成等操作,允许开发者组合出 windowed、dedupe、recursive 等自定义流操作,而不必依赖外部库。Gatherers 提供预置操作(如 window、teeing、fold),并支持与并行流配合。定稿后默认可用,无需 --enable-preview。

Stream Gatherers 填补了 Stream 中间操作的可扩展空白,让开发者用声明式方式实现复杂流处理。定稿后成为 Java 标准能力,JDK 25/26 继续使用。

#

28. JEP 517 为 JDK 26 HttpClient 增加 HTTP/3 时,HTTP/3-first、竞速连接、Alt-Svc 升级和仅 HTTP/3 URI 四种发现策略各有什么失败与回退语义?生产可观测性如何关联 QUIC 连接 ID 与连接迁移,并区分 UDP 被阻断、握手失败、0-RTT 被拒和回退 HTTP/2 造成的延迟

JEP 517 的四种 HTTP/3 发现策略(HTTP/3-first、竞速连接、Alt-Svc 升级、仅 HTTP/3 URI)各有什么失败与回退语义?生产可观测性如何关联 QUIC 连接 ID 与连接迁移,并区分各类延迟?

  • 四种发现策略的失败与回退
  • QUIC 连接 ID 与连接迁移
  • 生产可观测性

四种发现策略:HTTP/3-first 直接尝试 HTTP/3,失败(UDP 阻断、握手失败)回退 HTTP/2;竞速连接(Happy Eyeballs 风格)同时尝试 HTTP/3 与 HTTP/2,用先成功的,失败时回退到另一协议;Alt-Svc 升级在收到 HTTP/2 的 Alt-Svc 通告后升级到 HTTP/3,通告缺失则保持 HTTP/2;仅 HTTP/3 URI 强制使用 HTTP/3,失败则直接报错(不回退)。生产可观测性:记录 QUIC 连接 ID(connection ID)与连接迁移事件,将各请求的延迟按连接 ID 关联,区分四类延迟:UDP 被阻断(UDP 探测超时)、握手失败(握手前无响应)、0-RTT 被拒(服务端重放开局,回退 1-RTT 重试)、回退 HTTP/2(TCP 连接的延迟)。通过 JFR 与日志将延迟阶段与协议事件关联。

四种策略覆盖了"优先性能"到"优先兼容"的谱系。可观测性的关键是把网络阶段(UDP、握手、0-RTT、TCP)与协议选择、连接 ID 关联,才能定位延迟来源与回退原因。

#

29. JEP 526 Lazy Constants(2nd Preview,由 JEP 502 重命名)

JEP 526 Lazy Constants 第二次预览,由 JEP 502 重命名而来,其定位是什么?

  • JEP 526 与 JEP 502 的关系
  • Lazy Constants 的语义
  • 第二次预览状态

JEP 526(JDK 26,2nd Preview)将 JEP 502 的 Stable Values 重命名为 Lazy Constants,第二次预览。重命名反映其更聚焦"惰性初始化常量"的语义,而非"稳定值"。Lazy Constants 允许声明首次访问时初始化一次的常量,由 JVM 保证线程安全与单次初始化,避免类初始化锁与 holder idiom。第二次预览继续收集反馈,API 可能微调。

重命名是命名与语义收敛的体现。Lazy Constants 与 Stable Values 本质相同,只是名称更准确传达"惰性"与"常量"两个关键点。

#

30. JEP 526 第二次预览 Lazy Constants 的初始化、失败重试与可见性保证

JEP 526 第二次预览 Lazy Constants 的初始化、失败重试与可见性保证是什么?

  • 初始化语义
  • 失败重试
  • 可见性保证

Lazy Constants 的初始化语义:首次访问时执行初始化表达式,之后缓存结果,后续访问返回缓存值。初始化是惰性的(按需),由 JVM 保证线程安全。失败重试:若初始化表达式抛异常,该常量视为未初始化,后续访问会重新尝试初始化(类似 DCL 的失败重试)。可见性保证:初始化完成后,结果对所有线程可见(JVM 提供 happens-before 保证),无需额外同步。

惰性 + 单次初始化 + 失败重试 + 全线程可见,是 Lazy Constants 的核心语义。与 volatile 字段的 DCL 相比,JVM 封装了初始化与可见性,简化正确性。

#

31. JEP 529 Vector API(11th Incubator)

JEP 529 第 11 次孵化 Vector API 提供了什么能力?

  • Vector API 的孵化演进
  • SIMD 向量运算
  • 可移植性

JEP 529(JDK 26,11th Incubator)继续孵化 Vector API,提供 SIMD 向量运算的 Java 表达。相比 JEP 508(第 10 次),JEP 529 可能优化 API 的可移植性、掩码操作与标量回退。Vector API 支持 IntVector、FloatVector、DoubleVector、LongVector 等,以及掩码、广播、归约、重排等操作。平台不支持向量指令时自动回退标量实现,保证可移植性。经 11 次孵化仍未转正,说明 API 设计高度审慎。

Vector API 的多次孵化反映其目标(高性能 SIMD + 可移植)在 API 设计上的张力。JDK 26 继续收集反馈,优化运算模型与标量回退。

#

32. JEP 504 Remove the Applet API 的清理

JEP 504 移除 Applet API 的清理内容是什么?

  • Applet API 的移除
  • 移除的 API 与影响
  • 兼容性

JEP 504(JDK 26)移除 Applet API(java.applet.* 与 java.beans.AppletInitializer 等)。Applet 自 JDK 9 弃用(JEP 289),JDK 26 正式移除。移除的影响:依赖 Applet 的遗留 Web 应用与浏览器插件无法运行,相关 API 编译报错。清理包括移除 Applet 类、相关文档与依赖 Applet 的签名。由于 Applet 早已被现代 Web 技术取代,移除对现代应用影响极小。

Applet 的移除是"清理过时 API"的典型,遵循弃用 → 移除的生命周期。现代 Java 应用(Web、云原生)不依赖 Applet,移除无实质影响。

#

33. JEP 529 第十一次孵化 Vector API 的平台可移植性和标量回退

JEP 529 第 11 次孵化 Vector API 的平台可移植性和标量回退是什么?

  • 平台可移植性
  • 标量回退
  • 性能与正确性

Vector API 的可移植性核心是:同一份向量代码在不同平台(x86、ARM、RISC-V)上运行,由 C2 根据目标平台的 SIMD 指令集(AVX、NEON、RVV)生成最优向量指令。当平台不支持所需的向量指令或向量宽度不足时,自动回退到标量实现(每次处理一个元素),保证正确性,只是性能下降。JEP 529 继续优化可移植性与回退策略,让开发者用一套代码获得跨平台性能。

可移植性 + 标量回退是 Vector API 的基石:正确性不依赖平台,性能则按平台最大化。这也解释了为何 API 需长期孵化以平衡抽象与平台差异。

#

34. JEP 530 第四次预览原始类型模式在 instanceof 与 switch 中的穷尽性

JEP 530 第四次预览原始类型模式在 instanceof 与 switch 中的穷尽性是什么?

  • 原始类型模式
  • instanceof 与 switch 的穷尽性
  • 第四次预览状态

JEP 530(JDK 26,4th Preview)第四次预览原始类型模式(primitive patterns),允许在 instanceof 与 switch 中匹配原始类型。穷尽性(exhaustiveness)指 switch 表达式必须覆盖所有可能值的模式,否则编译错误;原始类型模式使 switch 能穷尽地匹配原始类型的取值范围(如 byte、short、int、long)。instanceof 中原始类型模式用于类型检查与值匹配,switch 中配合守卫条件穷尽覆盖。第四次预览说明 API 接近稳定但仍在调整。

穷尽性是 switch 表达式与语句的关键正确性保证。原始类型模式扩展穷尽性到原始类型,提升类型安全与表达式完整性。

#

35. 从 JDK 25 升级到 26 时如何建立已删除、弃用和行为变化清单

从 JDK 25 升级到 26 时,如何建立已删除、弃用和行为变化清单?

  • 升级清单的建立
  • 已删除/弃用/行为变化
  • 工具与验证

从 JDK 25 升级到 26,建立清单的方法:查阅 JDK 26 的 Release Notes(官方"JDK 26 Release Notes")与 JEP 列表,分类记录"已删除"(如 Applet API JEP 504)、"弃用"(如某些 API 的弃用警告)与"行为变化"(如 final 字段完整性 JEP 500、GC 默认值变化)。用 jdeprscan 扫描弃用 API 使用,用 jdeps 检查模块与内部 API 依赖,用 -Xlint 与编译警告收集弃用提示。将清单对应到应用的代码与依赖,逐项制定迁移与验证计划(编译、测试、灰度)。

跨版本升级需系统化盘点。Release Notes + JEP 列表 + jdeprscan/jdeps 工具,能将"未知变化"转化为可追踪的清单,配合编译与测试验证迁移。

#

36. 从 JEP 472 对 JNI 受限方法的预警、JEP 498 对 sun.misc.Unsafe 内存访问的告警,到 JEP 500 在 JDK 26 警告深反射修改 final 字段,这条 integrity-by-default 路线分别影响 JNI、Unsafe、反射和序列化框架的哪些调用?如何借助 native-access、Unsafe/final-field 诊断选项和 JFR 事件盘点依赖,并迁移到 FFM、VarHandle 或构造器注入

integrity-by-default 路线(JEP 472、JEP 498、JEP 500)分别影响 JNI、Unsafe、反射和序列化框架的哪些调用?如何借助诊断选项和 JFR 事件盘点依赖并迁移?

  • JEP 472 的 JNI 受限方法警告
  • JEP 498 的 Unsafe 内存访问告警
  • JEP 500 的 final 字段警告

integrity-by-default 路线逐步收紧 JVM 的"非标准"访问:JEP 472(JDK 24)对 JNI 受限方法(如在不支持时调用某些 JNI 功能)发出警告,影响 JNI 库的调用;JEP 498(JDK 24)对 sun.misc.Unsafe 的内存访问发出告警,影响依赖 Unsafe 的框架(如部分序列化、并发库);JEP 500(JDK 26)警告深反射修改 final 字段,影响反射依赖的框架注入与反序列化。盘点依赖:用 --enable-native-access 诊断选项盘点 JNI/FFM 使用,用 Unsafe/final-field 诊断选项(如 -XX:+UnsafeMemoryAccess)盘点 Unsafe 调用,用 JFR 事件(如 final 字段违规写入事件)盘点反射依赖。迁移:JNI 迁移到 FFM(Foreign Function & Memory API),Unsafe 内存访问迁移到 FFM 的 MemorySegment 或 VarHandle,final 字段修改迁移到构造器注入或 VarHandle。

这条路线是"终局收敛":把绕过语言约束的通道(JNI、Unsafe、反射)逐步规范化,强制迁移到标准 API(FFM、VarHandle)。诊断选项与 JFR 事件让迁移可量化、可追踪。