静态方法在子类中是“隐藏”而非重写,调用取决于声明类型而非实际类型;jvm用invokestatic指令编译期绑定,不参与动态分派;@override注解会编译失败;访问父类版本必须显式用类名限定。

Java 中静态方法在子类中被同名静态方法“隐藏”,不是重写,而是编译期确定的名称遮蔽行为。调用哪个版本,完全取决于变量或表达式的**声明类型**,而非实际对象类型。
静态方法隐藏的本质
静态方法属于类本身,不依赖实例,因此不进入虚方法表,也不参与运行时动态绑定。JVM 使用 invokestatic 指令直接根据编译时类型定位方法,不存在多态分派。
- 父类定义
public static void log() - 子类也定义
public static void log() - 这两个方法物理共存,互不覆盖,只是子类作用域内同名标识符指向了新实现
调用结果完全由声明类型决定
哪怕实际对象是子类实例,只要引用变量声明为父类类型,就调用父类静态方法。
-
Parent.log();→ 执行Parent.log() -
Child.log();→ 执行Child.log() -
Parent p = new Child(); p.log();→ 仍执行Parent.log()
@Override 注解会编译失败
这是语言层面的明确信号:Java 不认为这是重写行为。
- 若在子类静态方法上加
@Override,编译器报错 “method does not override or implement a method from a supertype” - 只有实例方法才能被
@Override标记,静态方法只能被隐藏
如何安全访问被隐藏的父类静态方法
不能靠转型或对象调用绕过,必须显式使用类名限定。
- 想调用父类版本 → 写
Parent.log(),不能写((Parent)childInstance).log() - 子类内部需调用父类静态方法 → 显式写
Parent.log(),不能用super.log()(super 不适用于静态上下文) - 避免歧义:若父子类都有
config(),建议改名如ParentConfig.config()和ChildConfig.config()
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











