JEP 405:在Java中扩展模式匹配的记录类
JEP 405,记录模式(预览版),已经从提议到目标 晋升为JDK 19的目标。在Project Amber的保护伞下,这个JEP建议用记录模式来增强语言,以解构记录值。记录模式可以与类型模式一起使用,以 "实现一个强大的、声明性的、可组合的数据导航和处理形式"。这仍然是一个预览功能。
JEP 394,instanceof的模式匹配,在JDK 16中交付,扩展了 **instanceof**操作符,以接受类型模式并执行模式匹配,请看下面的例子:
public void print(Object o) {
if (o instanceof Double) {
Double d = (Double) o;
System.out.println("d = " + d);
}
}
上面的代码可以用模式匹配来写,如下:
public void print(Object o) {
if (o instanceof Double d) {
System.out.println("d = " + d);
}
}
在上面的代码中。 **o**匹配类型模式 **Double d**如果在运行时, **o**是一个 Double.这就减少了显式的类型转换,使代码更短,更容易管理。
JEP 395,Records,引入了Record类,这是一个透明的数据载体,使开发者很容易编写不可变的对象。考虑一下下面的例子:
record Point(int x, int y) { }
有了它,开发者不再需要明确地编写构造函数、访问器方法和其他方法,如 toString(),和 hashCode().因此,代码变得干净,不那么啰嗦。
如果在一个代码块中使用了一个记录类的实例,开发者通常会使用其访问器方法提取数据,比如说:
public void printSum(Object o) {
if (o instanceof Point p) {
int x = p.x();
int y = p.y();
System.out.println(x + y);
}
}
在上面的代码中,模式变量 **p**被用来调用访问器方法 **x()**和 **y()**的值来获取 **x**和 y.在这里,没有其他使用 **p**在这里没有其他用途。在记录模式的情况下,变量 **p**就不再需要了。
现在可以重写上面的代码了:
public void printSum(Object o) {
if (o instanceof Point(int x int y)) {
System.out.println(x + y);
}
}
同样地,这允许开发者解构更复杂的对象图,考虑一下下面的代码例子:
enum Color {RED, GREEN, BLUE}
record ColoredPoint(Point p, Color color) {}
record Point(int x, int y) {}
record Square(ColoredPoint upperLeft, ColoredPoint lowerRight) {}
如果开发者需要在使用记录模式的模式匹配中打印左上角的 **ColoredPoint**在使用记录模式的模式匹配场景中,可以按以下方式进行解构:
public void printUpperLeftColoredPoint(Square s) {
if (s instanceof Square(ColoredPoint(Point(var x, var y), var color), var lowerRight))){
}
}
另一方面,上述解构后的代码的替代方案则要啰嗦的多。
此外,通过JEP 406,类型模式被扩展为在 **switch**此外,通过JEP 406,Pattern Matching for switch (Preview)(在JDK 17中交付)和JEP 420,Pattern Matching for switch (Second Preview)(在JDK 18中交付),类型模式被扩展为用于案例标签。有了这些,类似的解构可以用在 **switch**语句中使用。然而,关于这个JEP的工作仍在进行中,它有许多可以发展和扩展的方向。热心的开发者可以关注邮件列表并加入这个讨论。