instanceof 是 Java 中唯一能安全判断对象运行时实际类型的运算符,用于 Object 或父类/接口引用需确认具体子类时,语法为 object instanceof Type,返回 boolean,null 时恒为 false,不兼容类型编译报错。

instanceof 是 Java 中唯一能安全判断对象**运行时实际类型**的运算符,不是方法也不是函数,不能用于基本类型,也不能在编译期做类型推断。
什么时候必须用 instanceof?
当你拿到一个 Object 或父类/接口引用,但需要确认它底层是不是某个具体子类时——比如从集合里取元素、处理回调参数、解析 JSON 后的泛型擦除对象:
- 避免强制转型前抛
ClassCastException - 区分不同实现类的行为分支(如
Shape s是Circle还是Rectangle) - 配合泛型擦除后做运行时类型适配(如
List>里的元素)
instanceof 的语法和常见错误
格式是 object instanceof Type,返回 boolean。注意三点:
-
Type必须是编译期已知的类、接口或数组类型;不能是变量、String.class等 Class 对象 - 左边操作数为
null时,结果恒为false(不会 NPE) - 如果
Type和object的静态类型完全不兼容(如StringinstanceofThread),编译直接报错:Incompatible types
错误示例:obj instanceof clazz(clazz 是 Class> 变量)——这不行,得用 clazz.isInstance(obj)。
立即学习“Java免费学习笔记(深入)”;
替代方案:Class.isInstance() 和 Class.isAssignableFrom()
当类型信息只有运行时才能确定(比如来自配置、反射、插件系统),就得绕过 instanceof 的编译限制:
-
SomeClass.class.isInstance(obj)等价于obj instanceof SomeClass,但支持动态类型 -
SomeClass.class.isAssignableFrom(obj.getClass())判断是否是同类或父类,适用于更宽泛的继承关系检查 - 注意
obj.getClass()在null时会 NPE,要先判空
例如加载第三方插件类时,你只有类名字符串:Class.forName("com.example.PluginImpl").isInstance(instance)。
Java 14+ 模式匹配(instanceof 增强)
Java 14 起支持带变量声明的写法:if (obj instanceof String s) { ... },成功时自动把 obj 强转并赋给 s,作用域仅限于该 if 块内。
- 省去显式强转,减少重复代码
- 变量
s在条件为false时不可访问(编译报错) - 不支持
final修饰符以外的其他修饰符(如private String s非法)
老版本只能写两行:if (obj instanceof String) { String s = (String) obj; ... }。
真正容易被忽略的是:即使用了 instanceof,也别默认它能解决所有类型问题——比如泛型类型擦除后,List 和 List 在运行时都是 List,instanceof 无法区分。这时候得靠额外的元数据或封装逻辑。










