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

Java向上转型时父类可变参数方法优先执行的原因解析

向上转型场景下父类可变参数方法被优先调用的原因

先看你提供的示例代码:

public class Test {
    public static void main(String[] args) {
        A a = new B();
        a.foo("123");
    }
}

class A {
    public void foo(String... s) {
        System.out.println("A");
    }
}

class B extends A {
    public void foo(String s) {
        System.out.println("B");
    }
}

这段代码运行结果是打印A,核心原因是子类的foo(String s)并没有重写父类的foo(String... s),只是方法重载,再结合Java的方法绑定规则导致的:

1. 方法重写的前提不满足

Java里方法重写要求方法签名(方法名+参数列表)完全一致。父类的String... s是可变参数语法糖,本质等价于String[] s;而子类的foo(String s)参数是单个String,两者参数类型完全不同,所以这是子类新增的一个重载方法,而非对父类方法的重写。

2. 编译期的方法匹配逻辑

当你用父类类型A的引用调用foo("123")时,编译器只会在A类的方法中寻找匹配的方法:

  • A类只有foo(String...)这一个方法,编译器会自动把单个String参数包装成长度为1的String[](可变参数的语法特性),因此编译阶段就确定了要调用的是A类的foo(String...)方法。

3. 运行期的动态绑定不生效

Java的动态绑定(运行时根据实际对象类型调用方法)只针对被重写的方法。由于子类B并没有重写A的foo(String...),运行时找不到对应的重写实现,自然就执行父类A的方法逻辑。

如果想让子类的方法被调用,有两种方式:

  • 把引用强制转换为B类型:((B)a).foo("123"),此时编译器会匹配B类的foo(String s)
  • 让子类重写父类的可变参数方法:在B类中添加public void foo(String... s) { System.out.println("B"); }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:05:51