编程后端开发人员

在Java中,模式匹配是什么,它的引入阶段是怎样的,用于什么,应该注意哪些细节?请给一个例子。

用 Hintsage AI 助手通过面试

答案。

问题背景

模式匹配是一种来自于函数式和脚本语言的技术,允许在一个步骤中检查类型并提取数据。在Java中,模式匹配的发展始于Java 14(预览特性),在Java 16-17中得到了改进,并在最新版本中扩展到了switch。

问题

传统的类型检查和转换方法显得比较繁琐:

if (obj instanceof String) { String s = (String) obj; ... }

这样会产生多余的变量,大量的模板代码以及类型转换的错误风险。

解决方案

模式匹配允许在一个表达式中结合类型检查、新变量的声明和它的使用:

if (obj instanceof String s) { System.out.println(s.length()); }

类似的模式现在在switch语句中也出现了,这使得代码更加简洁且不易出错。

关键特点:

  • 简洁且安全的类型操作。
  • 减少类型转换错误的数量。
  • 易于支持代码并扩展到新类型。

有陷阱的问题。

模式匹配可以用于自定义类吗,还是只限于标准类型?

可以用于任何类。模式匹配适用于所有可以应用instanceof的类。

模式变量会在if/switch块外部可见吗?

不,模式匹配中声明的变量只在创建它的块内可见(例如,在if或case switch中)。

代码示例:

if (obj instanceof Integer i) { // i只在这个块内可见 System.out.println(i + 10); } // 在这里i不可用

可以将模式匹配与泛型一起使用吗?

可以,像这样:

Object list = List.of("a", "b"); if (list instanceof List<?> l) { System.out.println(l.size()); }

但由于类型擦除,与原始类型的操作和转换仍然受到限制。

常见错误和反模式

  • 假设模式匹配会自动处理null:如果对象为null,条件将不会满足(instanceof与null总是返回false)。
  • 在仅需getClass()方法的地方使用模式匹配。
  • 过于频繁地使用模式匹配可能会降低架构的清晰性,特别是在意图不明确时。

生活中的例子

负面案例

团队在所有情况下都实施了模式匹配,包括内部DTO、服务类及可以用多态实现的场景。代码过于依赖instanceof,类层次的角色变得模糊。

优点:

  • 快速实施。
  • 简洁风格。

缺点:

  • 架构设计失误。
  • 可读性降低。

正面案例

在项目中,模式匹配仅用于通用接口、辅助工具和处理未知类型的集合。面向对象的架构得到保留,模式仅在必要时使用。

优点:

  • 可读性高的代码。
  • 支持架构。

缺点:

  • 需要仔细设计和对JDK版本的了解。