instanceof是运行时类型校验机制,必须先判断再转型,防止classcastexception;java 14+支持模式匹配简化写法,且对null安全。

用 instanceof 校验对象真实类型,核心就一条:**先判断、再转型,不跳步、不取巧**。它不是语法糖,而是运行时防止 ClassCastException 的第一道防线。
向下转型前必须加校验
父类或接口引用指向子类实例是常态,但编译器只认声明类型。想调子类特有方法(比如 Dog.bark()),必须确认实际是 Dog:
- ✅ 安全写法:if (animal instanceof Dog) { Dog d = (Dog) animal; d.bark(); }
- ❌ 危险写法:Dog d = (Dog) animal; —— 若
animal实际是Cat或null,立刻崩溃 - ⚠️ 注意:Spring 的
getBean()、Android 的findViewById()返回的都是通用类型(Object/View),这类调用后几乎都得补instanceof
泛型擦除后取值要靠它兜底
运行时泛型信息已消失,List<string></string> 和 List<integer></integer> 都变成 List。从 Map<string object></string> 或 List<object></object> 取值后,不能凭 IDE 提示就强转:
Object val = map.get("time");- ✅ 正确:if (val instanceof LocalDateTime) { LocalDateTime t = (LocalDateTime) val; }
- ❌ 错误:LocalDateTime t = (LocalDateTime) map.get("time"); —— 类型不对时直接报错
- ? 补充:
val instanceof List成立,不代表能add();若需可修改,建议再检查具体实现类(如ArrayList)
区分 instanceof 和 getClass() 的使用场景
两者语义不同,选错会埋逻辑坑:
-
obj instanceof Animal→ 接受Animal及所有子类(Dog、Cat都返回true),适合多态分支处理 -
obj.getClass() == Animal.class→ 只匹配Animal本类,子类返回false,适合反序列化后要求精确版本的场景 - ✅ 更安全:
instanceof对null永远返回false;getClass()遇null直接抛NullPointerException
Java 14+ 模式匹配让代码更简洁
如果项目已升级到 Java 14+(需开启预览特性),可用新语法一步完成判断 + 绑定 + 非空保障:
- ✅ 简洁写法:if (obj instanceof String s && s.length() > 0) { System.out.println(s.toUpperCase()); }
- ⚠️ 注意:变量
s只在该if块内有效;不能用于三元表达式或字段赋值 - ✅ 同样适用于自定义类:if (data instanceof User u && u.isActive()) { ... }










