成员变量无多态性,编译和运行均看左边引用类型;成员方法具多态性,编译看左边、运行看右边实际对象类型;静态成员编译和运行均看左边,属类而非对象。

Java 多态中,成员变量和成员方法的访问行为完全不同,核心区别在于:成员变量不体现多态性,而成员方法才真正体现多态性。理解这一点,关键看“编译期”和“运行期”分别依据什么。
成员变量:编译看左,运行也看左
父类引用指向子类对象时(如 Fu f = new Zi();),访问成员变量始终以引用类型(左边)为准。即使子类定义了同名变量,也不会被使用。
- 编译阶段检查父类是否有该变量;没有就直接报错
- 运行阶段读取的也是父类中定义的那个变量值
- 子类中的同名变量只是独立存在,与多态访问无关
成员方法:编译看左,运行看右
调用方法时,编译只检查父类中是否存在该方法签名;运行时则根据实际创建的对象类型(右边)决定执行哪个版本,前提是该方法被子类重写(override)。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 如果子类重写了方法,运行时自动调用子类实现
- 如果子类没重写,向上查找父类实现并执行
- 若父类中根本不存在该方法,编译直接失败
静态成员:编译看左,运行也看左
静态方法和静态变量属于类,不属于对象,因此不参与多态。无论右边 new 的是哪个子类,只要引用类型是父类,调用的就是父类的静态成员。
- 本质是“类名.方法”的语法糖,JVM 在编译后已将调用目标固定为父类
- 静态方法不能被重写,只能被隐藏(hide),这和多态无关
为什么会有这种差异?
根本原因在于 JVM 的绑定机制不同:
- 成员变量在编译期就确定了内存偏移量,绑定发生在编译时(静态绑定)
- 成员方法在运行期通过虚方法表(vtable)动态查找,绑定发生在运行时(动态绑定)
- 静态成员与类绑定,与实例无关,自然不支持动态分派
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










