Java 未使用的变量 (_)
上次修改于 2025 年 5 月 28 日
本文介绍了如何使用下划线 (_
) 来表示 Java 中未使用的变量。这是 Java 21 (JEP 443) 中引入的一项功能,旨在帮助开发人员显式忽略未使用的参数。
未使用变量简介
在 Java 中,我们经常遇到需要声明参数或变量,但实际上并不使用它们的情况。
- 我们不需要的 Lambda 参数
- 我们想要忽略的模式匹配变量
- 我们不使用的异常参数
- 我们必须声明但未使用的接口方法参数
传统上,开发人员会:
- 给这些变量赋予无意义的名称(如
unused
或ignore
) - 抑制编译器/IDE 发出的 "unused variable" 警告
Java 21 引入了下划线 (_
) 作为特殊标识符,用于标记有意未使用的变量。在其他语言中通常被称为“discard”,它通过显式表明该变量是不必要的,从而增强了代码的清晰度,从而产生更简洁和可读的语法。
基本语法
下划线可以在多个上下文中使用
// Lambda parameters (param1, _) -> expression // Pattern matching if (obj instanceof String _) { ... } // Exception handling try { ... } catch (Exception _) { ... }
主要特点
_
只能在作用域中出现一次(在同一作用域中不能有多个_
)- 它不能被读取或写入
- 它不会创建实际的变量绑定
Lambda 表达式
在 lambda 参数中使用 _
允许我们忽略不需要的参数。这在函数式编程上下文中特别有用,因为我们可能只关心 lambda 表达式中的一个参数。
Main.java
void main() { Map<String, Integer> scores = Map.of("Alice", 90, "Bob", 85); // Only using the key, ignoring the value scores.forEach((name, _) -> System.out.println("Student: " + name)); // Only using the value, ignoring the key scores.forEach((_, score) -> System.out.println("Score: " + score)); }
此示例演示了如何忽略 Map.forEach
操作中的键或值。
模式匹配
模式匹配允许我们以更简洁的方式匹配类型和结构。我们可以使用 _
来忽略模式匹配中的值,当我们只关心类型或结构,而不关心实际值时,这可以使我们的代码更具可读性。
Main.java
void process(Object obj) { switch (obj) { case String _ -> System.out.println("It's a String"); case Integer _ -> System.out.println("It's an Integer"); case Double _ -> System.out.println("It's a Double"); default -> System.out.println("Unknown type"); } } void main() { process("Hello"); process(42); process(3.14); process(new Object()); }
这里我们使用 _
来匹配类型,而不将实际值绑定到变量。
异常处理
在异常处理中使用 _
,当我们不需要异常对象时。
Main.java
void readFile() { try { // File reading operation that might fail String fileName = "words.txt"; String content = Files.readString(Path.of(fileName)); System.out.println(content); } catch (IOException _) { System.out.println("Error occurred while reading file"); // Don't need the exception details } } void main() { readFile(); }
这显示了如何在不需要访问异常对象时处理异常。
记录模式
在使用记录进行模式匹配时,我们也可以使用 _
来忽略我们不关心的字段。
Main.java
record Point(int x, int y) {} void printX(Point p) { if (p instanceof Point(int x, _)) { System.out.println("X coordinate: " + x); } } void main() { printX(new Point(5, 10)); }
这里我们解构一个 Point
记录,但只关心 x
坐标。
最佳实践
何时使用 _
- 当接口需要参数,但我们的实现中未使用该参数时
- 当进行模式匹配时,我们只关心类型,而不关心值
- 当处理不需要异常对象的异常时
何时不使用 _
- 当稍后在代码中可能需要该变量时
- 当通过其名称记录参数的用途会很有价值时
- 在 Java 21 之前的代码中(它将被视为常规标识符)
兼容性注意事项
关于兼容性的重要提示
- 下划线
_
在 Java 1.0-20 中是有效的标识符 - 在 Java 21+ 中,
_
用作变量名时是一个特殊标记 - 在 Java 21+ 中,使用
_
作为变量名的现有代码将会中断 - 要迁移,请将现有的
_
变量重命名为其他名称
来源
在本文中,我们探讨了 Java 的未命名变量模式 (_
),这是一个简单但功能强大的功能,它通过显式标记未使用的变量,使代码更具可读性。
作者
列出所有Java教程。