向上转型是java多态的底层前提,编译器仅检查引用类型兼容性,不进行运行时检查或对象复制,零性能开销;但误用会导致classcastexception或访问错误。

向上转型不是语法糖,是 Java 多态的底层前提——它不报错、不警告、不触发任何特殊逻辑,但一旦你把它当成“安全的自动转换”来用,后面 ClassCastException 或空方法调用就等着你。
为什么 Parent p = new Child() 能直接编译通过
Java 编译器只检查引用类型声明(Parent)是否能访问右边对象的公开接口。只要 Child 是 Parent 的子类(或实现类),这个赋值就合法——它不关心运行时实际是什么,也不做任何对象复制或转换操作,只是把子类对象的内存地址,存进一个声明为父类类型的变量里。
常见错误现象:
你以为转型后能调用 Child 特有方法,结果编译失败;或者误以为转型会“丢失字段”,其实子类字段全在堆上,只是变量无法直接访问。
- 使用场景:多态参数传递(比如方法接收
Animal类型,传入Dog实例)、集合统一管理不同子类对象(List<shape></shape>存Circle和Rect) - 参数差异:构造函数、静态方法、私有方法不会被“继承”,所以转型后完全不可见
- 性能影响:零开销。没有类型擦除、没有反射、不触发任何运行时检查
什么时候会突然抛出 ClassCastException
只有当你试图向下转型((Child)p)且实际对象不是 Child 或其子类时,才会在运行时报这个错。向上转型本身从不抛异常。
媒体包提供了可管理各种媒体类型的类。这些类可提供用于执行音频和视频操作。除了基本操作之外,还可提供铃声管理、脸部识别以及音频路由控制。本文说明了音频和视频操作。 本文旨在针对希望简单了解Android编程的初学者而设计。本文将指导你逐步开发使用媒体(音频和视频)的应用程序。本文假定你已安装了可开发应用程序的Android和必要的工具,同时还假定你已熟悉Java或掌握面向对象的编程概念。感兴趣的朋友可以过来看看
容易踩的坑:
看到 Parent p = getSomething(); 就默认它是 Child,然后直接强转——但 getSomething() 可能返回 OtherChild 或甚至 Parent 本体。
- 务必先用
instanceof判断:if (p instanceof Child) { Child c = (Child) p; ... } - 注意 null 安全:
p instanceof Child对null返回false,但(Child)p对null不会抛异常(只是得到null) - 泛型擦除会让这种判断更隐蔽:比如
List<parent></parent>里混了各种子类,取出来再转型就得挨个判
父类引用调用方法,到底执行谁的
取决于方法是否被重写(override),而不是引用类型。这是动态绑定,由 JVM 在运行时根据实际对象类型决定。
关键区别:static 方法、final 方法、构造方法、私有方法——全部按引用类型(即父类)解析,不走动态绑定。
- 重写的方法:调用子类版本(哪怕变量是
Parent类型) - 重载的方法:只看编译期引用类型,和实际对象无关
- 字段访问:永远看引用类型!
p.field拿的是Parent的字段,哪怕子类有同名字段也不会覆盖
真正麻烦的地方不在转型本身,而在于你忘了它只是“换个角度看对象”——字段没变、内存没变、方法表没变,变的只是你能合法访问什么。一旦开始混用字段访问、静态方法、强制转型和泛型,边界就很容易模糊。







