instanceof 是防止 ClassCastException 最简单可靠的方式,需先检查后转型;仅适用于引用类型,基本类型须用包装类;与 getClass() 语义不同,前者支持多态,后者仅匹配本类。

直接在强制转型前用 instanceof 判断,是防止 ClassCastException 最简单也最可靠的方式。它不抛异常、不触发 NPE、零副作用,专为运行时类型守门而生。
必须先检查、再转型,顺序不能反
跳过 instanceof 直接强转,比如 (String)obj,一旦 obj 实际不是 String,运行时立刻崩溃。这不是编译错误,测试容易漏掉。
- 正确写法:先
if (obj instanceof String),再在块内安全转型 - 错误习惯:先转型再判断,或把转型写在 if 条件里(如
if ((String)obj != null)),这已经出错了 - 特别注意:Spring 的
getBean()、Android 的findViewById()等返回 Object/View 的 API,必须加这层检查
只对引用类型有效,基本类型要走包装类
instanceof 不能用于 byte、int、boolean 等基本类型——它们不是对象,没有运行时类型信息。
- ❌
byte b = 10; if (b instanceof Byte)→ 编译失败 - ✅ 改用包装类:
Byte b = 10;(自动装箱),再if (b instanceof Byte) - 常见对应关系:int ↔ Integer、boolean ↔ Boolean、char ↔ Character
区分 instanceof 和 getClass() ==,按需选择
两者语义不同,选错会导致逻辑偏差:
-
obj instanceof Animal:接受 Animal 及所有子类(Dog、Cat 都返回 true)→ 适合多态场景 -
obj.getClass() == Animal.class:只认 Animal 本类,子类返回 false → 适合严格版本控制或反序列化校验 - ⚠️
getClass()对 null 会空指针,instanceof对 null 永远返回 false,更安全
接口检查要谨慎,类型兼容 ≠ 行为可用
判断 obj instanceof List 成立,不代表你能调用 add() —— 因为 Arrays.asList() 返回的是不可变 List。
- 接口检查只保证“能转型”,不保证“能执行某操作”
- 若需确保可修改,建议进一步检查具体实现:
obj instanceof ArrayList或结合obj.getClass().getSimpleName()辅助诊断 - 更健壮的做法:用行为契约代替类型硬判,比如 try-add-catch 或提前调用
list instanceof RandomAccess等语义接口










