instanceof 运算符判断对象是否为某类、其子类或所实现接口的实例,返回布尔值;不适用于基本类型,左侧必须是引用类型且编译期需存在继承或实现关系;常用于转型前的安全检查。

Java 中的 instanceof 运算符**不判断“实际类型”的完整细节,而是检查对象是否属于某个类、其子类或所实现接口的实例**。它本质上是基于运行时的继承关系(类层次结构)做判断,不是获取类型名或反射式分析。
instanceof 判断的是继承链归属,不是类型字符串
它不返回 "java.lang.String" 这样的类型名,只返回 true 或 false。只要对象的运行时类是右侧类型的**自身、直接子类、间接子类,或实现了该接口**,结果就是 true。
-
new ArrayList() instanceof List→true(实现接口) -
new HashMap() instanceof Map→true(实现接口) -
new Date() instanceof Object→true(所有类都继承自 Object) -
null instanceof String→false(null 永远不满足任何 instanceof)
不能用于基本类型,且编译期有类型检查
左侧操作数必须是引用类型;如果编译器能确定左侧永远不可能是右侧类型(比如 Integer 变量去 instanceof String),会直接编译报错。
- ✅ 合法:
Object obj = "hello"; if (obj instanceof String) - ❌ 编译失败:
int x = 5; if (x instanceof String)(基本类型不允许) - ❌ 编译失败:
String s = ""; if (s instanceof java.util.Date)(无继承/实现关系,编译器可判定)
常用于安全向下转型前的防护
这是最典型也最实用的场景:避免 ClassCastException。
立即学习“Java免费学习笔记(深入)”;
- 先用
instanceof确认类型,再强制转换 - 例如:
if (obj instanceof Runnable) { ((Runnable) obj).run(); } - 注意:不要写成
if (obj instanceof Runnable) { Runnable r = obj; ... }—— 必须显式强转
替代方案:需要真正知道类型名时用 getClass()
如果目标是获取对象的**确切运行时类**(比如打印、日志、策略分发),应使用 obj.getClass().getName() 或 obj.getClass().getSimpleName()。
-
new String("a").getClass() == String.class→true -
new ArrayList().getClass() == ArrayList.class→true(但instanceof List也为 true) -
getClass()返回的是最具体的类,不包含父类或接口信息


















