JEP 440:记录模式
概括
_使用记录模式_增强 Java 编程语言以解构记录值。记录模式和类型模式可以嵌套,以实现强大的、声明性的、可组合形式的数据导航和处理。
历史
记录模式由JEP 405提议作为预览功能并在JDK 19中提供,并由JEP 432进行第二次预览并在JDK 20中提供。此功能与_模式匹配switch
_( JEP 441 )共同发展,两者之间具有相当大的交互性。该 JEP 建议根据持续的经验和反馈进一步完善该功能。
除了一些小的编辑更改之外,自第二次预览以来的主要更改是删除对增强语句标题中出现的记录模式的支持for
。此功能可能会在未来的 JEP 中重新提出。
目标
-
扩展模式匹配以解构
record
类的实例,从而实现更复杂的数据查询。 -
添加嵌套模式,支持更多可组合的数据查询。
动机
在 Java 16 中,JEP 394扩展了该instanceof
运算符以采用_类型模式_并执行_模式匹配_。这种适度的扩展允许简化熟悉的 instanceof-and-cast 习惯用法,使其更加简洁且不易出错:
// Prior to Java 16
if (obj instanceof String) {
String s = (String)obj;
... use s ...
}
// As of Java 16
if (obj instanceof String s) {
... use s ...
}
在新代码中,如果在运行时 的值是 的实例,则obj
匹配类型模式。如果模式匹配,则表达式为,并且模式变量被初始化为强制转换为的值,然后可以在包含的块中使用该值。String s``obj``String``instanceof``true``s``obj``String
字体模式一次性消除了许多铸造的情况。然而,它们只是迈向更具声明性、以数据为中心的编程风格的第一步。由于 Java 支持新的、更具表现力的数据建模方式,模式匹配可以让开发人员表达其模型的语义意图,从而简化此类数据的使用。
模式匹配和记录
记录(JEP 395)是透明的数据载体。接收记录类实例的代码通常会使用内置组件访问器方法提取数据(称为_组件)_ 。例如,我们可以使用类型模式来测试某个值是否是记录类的实例Point
,如果是,则从该值中提取x
和组件:y
// As of Java 16
record Point(int x, int y) {}
static void printSum(Object obj) {
if (obj instanceof Point p) {
int x = p.x();
int y = p.y();
System.out.println(x+y);
}
}
此处的模式变量p
仅用于调用访问器方法x()
和,该方法返回组件和y()
的值。 (在每个记录类中,其访问器方法与其组件之间都存在一一对应的关系。)如果该模式不仅能够测试某个值是否是 的实例,而且还能够从该值中提取和组件,那就更好了直接代表我们调用访问器方法。换句话说:x``y``Point``x``y
// As of Java 21
static void printSum(Object obj) {
if (obj instanceof Point(int x, int y)) {
System.out.println(x+y);
}
}
Point(int x, int y)
是一个_记录模式_。它将提取组件的局部变量声明提升到模式本身中,并在值与模式匹配时通过调用访问器方法来初始化这些变量。实际上,记录模式将记录的实例分解为其组件。