静态方法隐藏技术咨询:分析给定Marsupial与Kangaroo类代码
Java静态方法隐藏特性:Marsupial与Kangaroo代码深度分析
咱们来好好拆解这段代码,搞懂Java静态方法「隐藏」(Hiding)的核心逻辑——这是很多初学者容易踩坑的点,和实例方法的「重写」(Overriding)完全不是一回事!
首先补全代码的main方法方便演示(跑起来才能看清结果):
class Marsupial { public static boolean isBiped() { return false; } public void getMarsupialDescription() { System.out.println("Value of this : " + this.getClass().getName() + " , Marsupial walks on two legs: " + isBiped()); } } public class Kangaroo extends Marsupial { public static boolean isBiped() { return true; } public void getKangarooDescription() { System.out.println("Value of this : " + this.getClass().getName() + ", Kangaroo hops on two legs: " + isBiped()); } public static void main(String[] args) { Marsupial m = new Marsupial(); Kangaroo k = new Kangaroo(); Marsupial mk = new Kangaroo(); // 测试调用 m.getMarsupialDescription(); k.getMarsupialDescription(); k.getKangarooDescription(); mk.getMarsupialDescription(); // 直接调用静态方法 System.out.println("Marsupial.isBiped(): " + Marsupial.isBiped()); System.out.println("Kangaroo.isBiped(): " + Kangaroo.isBiped()); System.out.println("mk.isBiped(): " + mk.isBiped()); } }
核心概念:静态方法「隐藏」vs 实例方法「重写」
- 实例方法重写:动态绑定,运行时根据对象的实际类型确定调用哪个方法,是多态的核心。
- 静态方法隐藏:静态绑定,编译时就根据变量的声明类型(而非运行时类型)确定调用哪个方法。子类的同名静态方法只是「隐藏」父类的,而非「重写」——你甚至不能给静态方法加
@Override注解,编译器会直接报错!
运行逻辑逐行拆解
先看代码的运行结果:
Value of this : Marsupial , Marsupial walks on two legs: false Value of this : Kangaroo , Marsupial walks on two legs: false Value of this : Kangaroo, Kangaroo hops on two legs: true Value of this : Kangaroo , Marsupial walks on two legs: false Marsupial.isBiped(): false Kangaroo.isBiped(): true mk.isBiped(): false
逐个分析关键点:
m.getMarsupialDescription()- m是
Marsupial实例,this.getClass()返回Marsupial;isBiped()是静态方法,编译时绑定到Marsupial.isBiped(),所以返回false。
- m是
k.getMarsupialDescription()- k是
Kangaroo实例,this.getClass()返回运行时类型Kangaroo;但getMarsupialDescription是父类方法,里面的isBiped()调用的是当前类(Marsupial)的静态方法,和this的运行时类型无关,所以仍然返回false——这是最容易混淆的点!
- k是
k.getKangarooDescription()- 这是Kangaroo自身的方法,里面的
isBiped()编译时绑定到Kangaroo.isBiped(),所以返回true。
- 这是Kangaroo自身的方法,里面的
mk.getMarsupialDescription()- mk的声明类型是
Marsupial,运行时类型是Kangaroo;getMarsupialDescription是实例方法,动态绑定后执行父类方法,里面的isBiped()还是调用Marsupial的静态方法,返回false——静态方法完全不看运行时类型。
- mk的声明类型是
直接调用静态方法
Marsupial.isBiped()和Kangaroo.isBiped():用类名调用结果明确,分别返回false和true。mk.isBiped():mk的声明类型是Marsupial,编译时绑定到Marsupial.isBiped(),返回false,再次验证静态方法看声明类型的特性。
关键特性总结
- 静态方法属于类,不属于任何实例,永远不要用实例对象调用静态方法(虽然语法允许),这会造成混淆,应该直接用类名调用,清晰明确。
- 子类静态方法只能「隐藏」父类同名静态方法,不能「重写」,调用时完全由编译时的声明类型决定,和运行时类型无关。
- 实例方法中的
this.getClass()返回运行时类型,但这对静态方法的调用没有影响,静态方法只看当前代码所在类或变量的声明类型。
内容的提问来源于stack exchange,提问作者Number945
相关产品推荐
相关产品推荐

