instanceof 的模式匹配
测试类型的同时绑定变量
instanceof 的模式匹配 是 CoddyKit 上的免费 Java Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。
类型判断的模式匹配
过去使用 instanceof 的方式是先测试再进行类型转换。模式匹配将测试和类型转换合并为一步,并在测试成功时绑定一个带类型的变量。
旧式样板代码
传统代码会先检查类型,然后将值转换到一个新变量中。这种写法重复繁琐,也很容易出错。
public class Main {
public static void main(String[] args) {
Object obj = "hello";
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
}
}新写法
类型模式会在同一行声明变量:if (obj instanceof String s)。条件为真时,s 已经是完成类型转换的值。
public class Main {
public static void main(String[] args) {
Object obj = "hello";
if (obj instanceof String s) {
System.out.println(s.length());
}
}
}绑定变量
变量 s 称为模式变量。只要编译器能够证明模式匹配成功,该变量就处于作用域内,因此代码更短也更安全。
在条件中使用
在同一个 if 条件中,您可以在 && 之后使用模式变量,因为在该分支中匹配一定成功。
public class Main {
public static void main(String[] args) {
Object obj = "developer";
if (obj instanceof String s && s.length() > 5) {
System.out.println("Long string: " + s);
}
}
}否定与流程作用域
使用否定时,作用域会智能地发生变化。在 if (!(obj instanceof String s)) return; 之后,变量 s 在方法的剩余部分处于作用域内,因为只有匹配成功时程序才会继续执行。
public class Main {
static int safeLength(Object obj) {
if (!(obj instanceof String s)) {
return -1;
}
return s.length();
}
public static void main(String[] args) {
System.out.println(safeLength("abc"));
System.out.println(safeLength(42));
}
}替代 equals 与类型转换
一个典型用法是编写简洁的 equals 重写:在一行中测试类型并绑定变量,然后比较字段。
public class Main {
static final class Point {
final int x, y;
Point(int x, int y) { this.x = x; this.y = y; }
public boolean equals(Object o) {
return o instanceof Point p && p.x == x && p.y == y;
}
public int hashCode() { return x * 31 + y; }
}
public static void main(String[] args) {
System.out.println(new Point(1, 2).equals(new Point(1, 2)));
System.out.println(new Point(1, 2).equals(new Point(3, 4)));
}
}处理混合类型
带模式的链式 else if 分支可以简洁地根据多种可能的类型进行分派。
public class Main {
static String describe(Object obj) {
if (obj instanceof Integer i) {
return "int " + (i * 2);
} else if (obj instanceof String s) {
return "string of length " + s.length();
} else {
return "unknown";
}
}
public static void main(String[] args) {
System.out.println(describe(21));
System.out.println(describe("hello"));
System.out.println(describe(3.14));
}
}空值永远不会匹配
instanceof 模式对 空值为 false,与传统运算符一样。因此,模式变量永远不会绑定到空值,从而避免了常见的空指针异常来源。
public class Main {
public static void main(String[] args) {
Object obj = null;
if (obj instanceof String s) {
System.out.println("matched: " + s);
} else {
System.out.println("null or not a String");
}
}
}更简洁、更安全的代码
模式匹配移除了多余的类型转换,缩小了作用域,使您无法误用变量,而且读起来几乎就像英语一样。这是现代 Java 中推荐的写法。
综合运用
使用模式格式化不同输入的小型分派器。
public class Main {
static String format(Object o) {
if (o instanceof Double d) return String.format("%.1f", d);
if (o instanceof Integer i) return Integer.toString(i);
if (o instanceof String s && !s.isBlank()) return s.trim();
return "n/a";
}
public static void main(String[] args) {
System.out.println(format(3.14159));
System.out.println(format(99));
System.out.println(format(" spaced "));
System.out.println(format(null));
}
}快速检查
检验您对 instanceof 模式的理解。
回顾
您学习了 instanceof 的模式匹配。
- 它将类型检查和类型转换合并为一个表达式。
- 模式变量的作用域限定在能够确认匹配的位置。
- 模式对空值为 false,从而避免空指针异常。
- 它简化了 equals 重写和类型分派。
常见问题解答
「instanceof 的模式匹配」课时是免费的吗?
是的 — 「instanceof 的模式匹配」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。
「instanceof 的模式匹配」这节课中我会学到什么?
测试类型的同时绑定变量 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Java Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「instanceof 的模式匹配」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Java Academy 课中编写并运行代码吗?
能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- instanceof 的模式匹配
- Record 模式
- 嵌套 Record 模式
- switch 中的模式