向上转型安全自动,向下转型需先用instanceof验证真实类型,否则抛ClassCastException;泛型擦除和接口转换同理,必须确保对象实际类型匹配。

向上转型是安全的,编译器自动允许;向下转型有风险,不加判断就强制转换会直接触发 ClassCastException。关键不在“转不转”,而在“转之前有没有确认对象真实类型”。
向上转型:自动、安全、无需检查
子类对象赋值给父类引用,属于天然兼容的操作。JVM 知道 Dog 是 Animal 的一种,所以:
- Animal a = new Dog(); —— 合法,不抛异常
- 此时 a 只能调用 Animal 定义的方法,不能直接用 Dog 特有方法
- 这是多态的基础,也是设计上鼓励的做法
向下转型:必须验证,否则必崩
把父类引用当作子类来用,本质是“冒险猜测”。JVM 不信你,必须你自己证明:
- Dog d = (Dog) a; —— 如果 a 实际指向的是 Cat 或纯 Animal,立刻报错
- 正确做法是先用 instanceof 判断:
if (a instanceof Dog) { Dog d = (Dog) a; } - 注意:instanceof null 返回 false,不会空指针,可放心用
集合里取元素时最容易踩坑
泛型擦除后,List
- 错误写法:String s = (String) list.get(0); —— list 里万一存了 Integer 就崩
- 稳妥写法:Object obj = list.get(0); if (obj instanceof String) { String s = (String) obj; }
- 更推荐用泛型明确类型:List
stringList ,让编译器提前拦截非法添加
接口转换也要看实现
把对象转成某个接口,不是看它“能不能装”,而是看它“有没有真正实现”:
- Serializable s = (Serializable) obj; —— 若 obj 所属类没声明 implements Serializable,照样 ClassCastException
- 同样要先判断:if (obj instanceof Serializable)
- 注意匿名内部类、Lambda 表达式生成的实例也需满足接口实现条件










