JEP 401 Value Objects (Preview) 已合并至 OpenJDK master 分支
概述
JEP 401 Value Objects (Preview) 和 JEP 539 Strict Field Initialization 已合并到 OpenJDK master 分支。
该 pull request #31120 整合了 2,934 个 commit,包含 208,011 次新增和 13,161 次删除,实现了 JEP 401 的首次预览,并同时实现了相关的 JEP 539。在解决合并冲突并获得所需批准后,该变更于 2026 年 7 月 31 日准备好进行集成。所有生成的代码应在 valhalla/lworld 仓库中进一步开发,该仓库通过每周标签与 jdk/master 同步。
语言实现
Java 语言现在允许声明定义不可变、无身份(identity-free)类型的 value classes。
此变更对应于子评审 JDK-8317277 (Java language implementation of value objects)。Value classes 可以用作泛型类型的类型参数,例如 List<T> 和 Comparable<T>。正如一位评论者所指出的:“像 List<T> 和 Comparable<T> 这样的泛型类型可以使用 value classes 作为类型参数进行实例化。JEP 218, Generics over Primitive Types (with revisions),将允许泛型类和方法在由 value class 类型参数化时,对字段、数组和局部变量的布局进行特化。好吧,这太酷了!JVM 需要更多方法来利用编译时已知的数值大小,以实现更好的内存分配和优化。” 目前的预览版尚未包含 JEP 218 所承诺的特化功能,这仍是未来的步骤。
JVM 实现
JVM 已更新,可以在没有传统对象头的情况下分配 value objects,并按照 JEP 539 预览的内容强制执行严格的字段初始化。 这项工作在子评审 JDK-8317278 (JVM implementation of value objects) 中进行跟踪。JVM 现在将 value objects 视为 inline types,消除了对象身份及相关的 header 开销。一位评论者质疑了其影响:“如果我理解得没错,那么 Integer 将变成一个 value class,它的每个实例都会失去其对象身份。我对细节了解不多,但从一开始来看,这对我来说似乎是一个相当大胆的举动。” 另一位询问了数据限制:“最新状态是什么?是否仍然限制为 63 位数据加 1 位用于可空性?” 这些问题反映了该功能的预览性质。
标准库更新
核心库的调整在适应 value objects 的同时,保留了诸如 String 等类的现有引用类型。 子评审 JDK-8317279 (Standard library implementation of value objects) 更新了 JDK 以支持 value types。一位社区成员观察到了剩余的区别:“真的很酷,遗憾的是字符串尽管具有不可变性,但不能像 Integer 那样完全无法区分。” 与此同时,另一位对进展表示赞赏:“现代 Java 简直太棒了。我真的无法理解为什么现在还会使用除了 OG 以外的任何东西!”
与 JEP 539 的关系
JEP 401 依赖于 JEP 539 对严格字段初始化的预览,以保证 value object 的字段在使用前已完全初始化。 Pull request 描述明确指出,JEP 539 是在同一个代码库中实现的,因为 JEP 401 依赖于严格的字段初始化。原始材料中没有关于此依赖关系的进一步评论。
社区反应
Hacker News 的评论者对此次合并表示欢迎,认为这是一个性能里程碑,同时讨论了它的范围及其与更广泛的 Valhalla 计划的关系。
我对此深有同感:我主要热爱 Java 这门语言。缺乏 value types 是实现某些类型性能的最大障碍。我非常期待语言的这一演进。 – @timmg 我认为理解这项功能涵盖了什么以及没有涵盖什么非常重要。这“仅仅是 Valhalla 的第一部分”。参见例如 https://www.jvm-weekly.com/p/project-valhalla-explained-how-... 的优秀总结 – @mormegil 我总是对 Java 领导者们在推出推动语言前进、同时尽可能保持向后兼容的变更时所投入的思考和工作感到惊讶。 – @ludovicianul 现代 Java 简直太棒了。我真的无法理解为什么现在还会使用除了 OG 以外的任何东西! – @exabrial 终于看到这里的进展了,这真的很棒。几十年来,缺乏 value types 一直是 Java 最大的性能陷阱之一 – @swiftcoder 有趣的是,虽然两种语言仍在接收新功能,但 Java 似乎走在 JavaScript 前面:- Java 很早就有了 Date 的现代替代方案,而 JavaScript 最近标准化的 Temporal API 在 Safari 中仍不受支持。- Java 有 switch expressions,而 JavaScript 尽管受 Scheme 影响,却没有。- 现在 Java 正在获得 value objects,而 JavaScript 等效的 tuples & records 提案已被撤回。 – @sheept 泛型类型如
List<T>和Comparable<T>可以使用 value classes 作为类型参数进行实例化。JEP 218, Generics over Primitive Types (with revisions),将允许泛型类和方法在由 value class 类型参数化时,对字段、数组和局部变量的布局进行特化。好吧,这太酷了!JVM 需要更多方法来利用编译时已知的数值大小,以实现更好的内存分配和优化。 – @ivanjermakov 如果我理解得没错,那么 Integer 将变成一个 value class,它的每个实例都会失去其对象身份。我对细节了解不多,但从一开始来看,这对我来说似乎是一个相当大胆的举动。 – @weinzierl 之前关于 project Valhalla 的 HN 讨论:https://news.ycombinator.com/item?id=48595511 – @kuhsaft 我总是忘记这部分设计的理由——为什么 value semantics 是在声明处而不是使用处实现的?为什么类作者必须将其声明为 value type?我知道 Brian 已经反复讨论过这个问题很多次了,但我总是忘记理由。 – @swaranga 太棒了,尽管特化泛型仍然缺失。我认为这些改进对 Scala 尤其有利,因为它是一门如此强大的语言,但在 JVM 上进行抽象的代价是巨大的。 – @pregnenolone 2934 个 commit,天呐……巨大的工作量。 – @germandiago Really cool, shame that strings can’t be fully indistinguishable like Integer despite their immutability – @parallax_error What's the latest status? Is it still limited to 63-bits of data plus 1 bit for nullability? – @HexDecOctBin The MR is closed This is it https://github.com/openjdk/jdk/commit/cc278dbb8a1ca0754d5842... – @ligarota 这占 Valhalla 的多少?50%?90%? – @whytevuhuni 收藏备用 – @hn4yci687u