JEP 443: 未命名模式和变量(预览)
JEP 443,即未命名模式和变量,已从Targeted状态完成,成为JDK 21的预览特性。该JEP旨在通过引入未命名模式和未命名变量来增强Java语言,分别用于在模式匹配中省略记录组件的名称和类型,以及声明但不使用变量。这两种特性均使用下划线字符(_)表示。
未命名模式
未命名模式主要用于简化数据处理,尤其是在处理记录类时。它允许开发者在模式匹配中省略记录组件的类型和名称,从而显著提高代码的可读性。例如:
if (r instanceof ColoredPoint(Point p, _)) {
// ...
}在这个例子中,如果Color c组件在if块中不需要,开发者可以简单地使用下划线省略它,使代码更加简洁。
未命名变量
未命名变量适用于必须声明但不使用变量值的场景,如循环、try-with-resources语句、catch块和lambda表达式。例如:
for (_ : orders) {
if (total < limit) total++;
}在这个循环中,order变量未被使用,开发者可以用下划线替代,使代码更加清晰。
启用预览特性
未命名模式和变量是预览特性,默认情况下是禁用的。要使用这些特性,开发者需要在编译和运行时启用预览功能。例如:
javac --release 21 --enable-preview Main.java
java --enable-preview Main也可以使用源代码启动器直接运行:
java --source 21 --enable-preview Main.java在jshell中使用时,也需要启用预览特性:
jshell --enable-preview高级用例
未命名模式在嵌套模式匹配中尤为有用。例如,如果只需要Point的x坐标,可以省略y和Color组件:
if (r instanceof ColoredPoint(Point(int x, _), _)) {
// ...
}在switch语句中,未命名模式变量可以用于多个执行相同操作且不使用变量的情况:
switch (b) {
case Box(RedBall _), Box(BlueBall _) -> processBox(b);
case Box(GreenBall _) -> stopProcessing();
case Box(_) -> pickAnotherBox();
}在lambda表达式中,如果参数无关紧要,可以使用未命名变量:
stream.collect(Collectors.toMap(String::toUpperCase, _ -> "No Data"));在try-with-resources语句中,如果代码不使用资源变量,可以使用未命名变量:
try (var _ = ScopedContext.acquire()) {
// No use of acquired resource
}在catch块中,如果异常参数的名称无关紧要,可以使用未命名变量:
try {
int i = Integer.parseInt(s);
} catch (NumberFormatException _) {
System.out.println("Bad number: " + s);
}下划线的历史
从Java 8开始,下划线作为标识符的使用被不鼓励,并在Java 9中成为编译时错误。因此,现有代码中使用下划线作为变量名的情况很少。如果存在这种情况,需要修改代码以避免使用下划线。
总结
JEP 443是提高Java代码可读性和可维护性的重要一步。它允许开发者省略不必要的组件和变量,减少代码混乱,使代码更易于理解。随着开发者对这一特性的熟悉,预计它将成为Java编程的重要组成部分。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。