6 月 15 日,Oracle 工程师 Lois Foltan 在 OpenJDK 邮件列表确认,JEP 401:Value Classes and Objects 将合入 OpenJDK 主线,目标进入 JDK 28。
这个 PR 很大。约 19.7 万行代码,1816 个文件。集成期间,其他较大的提交还被要求暂缓。
真正有意思的地方不在“Java 又多了一个特性”。Project Valhalla 从 2014 年正式启动,到现在才走到主线门口。它说明 Java 对象模型里那批绕不开的性能成本,终于有了可验证的第一阶段方案。
但边界也要说清。JEP 401 仍是 preview,默认关闭。Brian Goetz 也明确说过,这只是 Valhalla 的第一部分。
JDK 28 拿到的是 value class,不是完整 Valhalla
JEP 401 的核心口号是:codes like a class, works like an int。
开发者仍然写类。可以有封装、方法、字段名和构造校验。但 JVM 有机会用更接近 primitive 的方式存放和处理这类对象。
这句话容易被误读。value class 不是“零成本对象”。它更像是给 JVM 和语言模型一个新约定:在合适条件下,减少对象身份带来的负担,争取更紧凑的布局和更少的间接访问。
| 问题 | JDK 28 目标内容 | 现实边界 |
|---|---|---|
| JEP 401 | Value Classes and Objects | 预览特性,默认关闭 |
| Valhalla 进度 | value classes 第一阶段 | 不是完整终局 |
| 泛型 | 为 specialized generics 铺路 | JDK 28 不交付 specialized generics |
| 性能 | 争取更紧凑布局、更少指针跳转 | 不承诺所有场景都扁平化 |
| 使用方式 | 可用于验证 API、框架、工具链适配 | 不适合当生产稳定能力押注 |
对 Java/JVM 开发者来说,下一步不是马上迁移业务核心代码,而是准备验证环境。
最相关的两类人会先动起来。
一类是做低延迟、内存敏感系统的团队,比如交易、数据库、分析引擎、图形处理。它们会用 JDK 28 预览版跑基准,看对象数量、GC 压力、缓存命中和延迟曲线有没有实打实变化。
另一类是框架和工具链维护者。反射、序列化、字节码增强、ORM、测试框架,都要检查自己面对 value class 时会不会把语义理解错。
普通企业团队更适合观望。JEP 401 还是 preview,语义可能调整,默认也不开。把它写进中长期性能改造计划可以,直接按稳定特性排期,风险偏高。
Valhalla 瞄准的是引用对象的硬成本
Java 里,int、long、double 这类 primitive 是少数特例。大多数数据以对象形式存在。
一个 Point 变量通常不是两个数字本身,而是一个引用。它指向堆上的对象。对象有对象头,要分配,要被 GC 管理。访问字段时,还可能多走一次指针跳转。
数组里问题更明显。
Point[] 往往是一组引用。真正的 Point 对象散落在堆上。CPU 缓存按 cache line 取数据,连续数据更容易命中。对象到处跳,缓存局部性就差。
逃逸分析能帮一部分场景。JIT 如果看清对象不会逃出去,就可能消除分配。但这不是稳定契约。代码一重构,对象进入字段、数组、接口边界,优化就可能失效。
所以很多高性能 Java 代码早就走了另一条路:手写扁平数据。
图像处理把 RGB 塞进字节数组。数据库和游戏系统维护结构化数组。速度上去了,类型安全、字段语义、封装也被削薄了。
Valhalla 想补的就是这个缺口:让开发者少在“干净对象模型”和“裸数据结构”之间二选一。
这里也能看出 Java 的难处。C# 的 struct、C++ 的值语义、Rust 更直接的数据布局控制,都更早把这件事交给开发者。Java 不能这么轻。它要兼容既有 JVM、类库、字节码、GC 和泛型擦除。
慢,不全是拖延。更像负重过桥。
从 Q World 到 L World,路线收敛后才敢进主线
Valhalla 早期走过 Q World 路线。新 value 类型被当成和普通对象不同的一套体系:不同描述符、不同字节码、不同顶层类型。
这个方向很直观。问题也大。JVM 类型系统会被迫长出两套分支,生态工具也要跟着承受复杂度。
后来的 L World 是关键转向。value 类型共享普通引用使用的 L descriptor,把模型尽量统一到更兼容的承载方式上。
这个选择也带来现在的分阶段路线:先交付 value classes,再处理 specialized generics。
术语变化本身就说明设计改过几轮。早期叫 value types,后来有 inline classes,再到 primitive classes 的双投影模型,如今 JEP 401 落到 value classes。它们不是同一个词换皮,而是对应不同阶段的模型取舍。
| 阶段/术语 | 大致含义 | 对今天读者的提醒 |
|---|---|---|
| value types | 早期方向 | 不要直接等同于 JEP 401 |
| inline classes | 中间设计阶段 | 反映过一轮语义调整 |
| primitive classes | 双投影模型阶段 | 不是 JDK 28 这次的简单标签 |
| value classes | JEP 401 当前交付目标 | 以 preview 进入 JDK 28 |
| specialized generics | 后续重要阶段 | 这次不交付 |
接下来最该看三件事。
第一,JEP 401 在预览期的语义会不会继续调整。preview 的价值就是让开发者试,也允许语言和 VM 团队改。
第二,HotSpot、GraalVM、主流框架和字节码工具的适配速度。value class 不只影响写代码的人,也影响所有“读懂代码结构”的工具。
第三,真实应用里的收益是否稳定。demo 跑得快不够。大型 Java 服务升级 JDK 后,能不能得到更少内存、更低 GC 压力、更可解释的延迟曲线,才是硬指标。
所以,JDK 28 的 Valhalla 更像一次开闸试水。水已经进渠,但离全网灌溉还远。开发者该兴奋,也该把预览、边界和工具链成本写进同一张清单。
