静态方法隐藏非重写,调用取决于引用类型而非对象类型:父类引用调用父类方法,子类引用调用子类方法,二者并存不覆盖。

子类隐藏父类同名静态方法,本质不是重写,而是“静态绑定下的名字遮蔽”。Java 中静态方法不参与多态,调用完全取决于**引用类型(编译时类型)**,而非实际对象类型。所以区分关键在于:谁在调用、用什么类型调用。
静态方法隐藏的本质
当子类定义了一个与父类同名、同参数列表的静态方法时,子类该方法不会覆盖父类方法,而是“隐藏”它。父类方法依然存在,只是被同名子类静态方法遮住了访问路径。
- 父类静态方法仍可通过 父类名.方法名() 直接调用
- 子类静态方法只能通过 子类名.方法名() 或 子类引用(编译时类型为子类).方法名() 调用
- 若用父类引用指向子类对象,再调用该静态方法,执行的是父类的静态方法(不是子类的)
代码示例看区别
假设父类和子类如下:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
class Animal {
public static void info() {
System.out.println("Animal.info()");
}
}
class Dog extends Animal {
public static void info() {
System.out.println("Dog.info()");
}
}
不同调用方式结果不同:
- Animal.info() → 输出 Animal.info()
- Dog.info() → 输出 Dog.info()
- Animal a = new Dog(); a.info(); → 输出 Animal.info()(因为 a 是 Animal 类型)
- Dog d = new Dog(); d.info(); → 输出 Dog.info()
和实例方法重写的对比
这是最容易混淆的点:
- 实例方法同名同参:是重写(@Override),运行时根据对象实际类型决定调用哪个版本
- 静态方法同名同参:是隐藏,编译时就根据引用声明类型决定调用哪个版本
- 静态方法不能加 @Override 注解,否则编译报错
如何避免误用和排查问题
开发中常因疏忽把本该是实例方法的逻辑写成静态,导致行为不符合预期:
- 如果希望子类提供不同实现并支持多态,就不要用 static,改用普通实例方法
- 若确实需要工具类风格的静态方法,命名时可加前缀(如
dogInfo()/animalInfo())或用不同名,避免隐藏歧义 - IDE 通常会在子类静态方法上提示 “Method hides a static method in the superclass”,注意这类警告
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










