You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

超类型变量调用子类型方法及静态与重写方法输出差异的疑问

为什么静态方法与重写实例方法的调用结果不同?

嘿,这个问题问到点子上了!核心原因其实是Java里静态方法和实例方法的调用绑定机制完全不一样,咱们掰开揉碎了说:

1. 静态方法:编译期静态绑定,看「引用变量的类型」

静态方法本质上是属于类的,不属于任何具体对象。所以当你用超类型变量指向子类型对象时,调用静态方法的逻辑在编译阶段就确定了——JVM只会看你声明的变量类型是什么,完全不管这个变量实际指向的对象是谁。

举个简单例子:

class Parent {
    public static void show() {
        System.out.println("Parent static method");
    }
}

class Child extends Parent {
    public static void show() {
        System.out.println("Child static method");
    }
}

// 测试代码
Parent p = new Child();
p.show(); // 输出 "Parent static method"

这里变量p的类型是Parent,所以编译时就绑定了Parent的静态方法,哪怕实际对象是Child也没用。而且注意:子类的静态方法不是「重写」父类的,只是隐藏了父类的同名静态方法,这是完全不同的概念。

2. 重写的实例方法:运行期动态绑定,看「实际对象的类型」

而实例方法的重写是Java多态的核心,它的调用逻辑是在运行阶段才确定的——JVM会去看变量实际指向的那个对象是什么类型,然后调用该类型中被重写的方法。

还是用刚才的例子改一改:

class Parent {
    public void show() {
        System.out.println("Parent instance method");
    }
}

class Child extends Parent {
    @Override
    public void show() {
        System.out.println("Child instance method");
    }
}

// 测试代码
Parent p = new Child();
p.show(); // 输出 "Child instance method"

这里变量p虽然声明是Parent,但实际指向的是Child对象,所以运行时JVM会找到Child中重写的show()方法执行,这才是多态的体现。

为什么两者结果不一样?

简单来说:

  • 静态方法是「类层面」的调用,和对象无关,所以看变量类型;
  • 重写的实例方法是「对象层面」的调用,为了实现多态,所以看实际对象类型。

这就是为什么你看到的输出会有差异——重写方法的设计目的就是让同一个调用在不同对象上有不同表现,和静态方法的绑定逻辑完全相反,自然结果不会一致啦。

内容的提问来源于stack exchange,提问作者psFreak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:17:12