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

Java变量传递时的多态问题:为何调用print(X)而非print(Y)?

为什么x.print(x)调用的是Y.print(X)而不是Y.print(Y)?

这问题问到点子上了,本质是要搞懂Java里方法重载(overload)和方法重写(override)的绑定时机差异,我给你一步步拆解清楚:

先看代码里的核心逻辑:

X x = new Y();
x.print(x);
System.out.println(x.getClass()); // 输出class Y

第一步:编译时锁定方法签名(重载的选择逻辑)

Java编译器处理x.print(x)的时候,只认变量x的声明类型(也就是X),完全不会管它实际指向的对象是Y。

  • 看X类的方法:有print(X)和print(Y)两个重载方法
  • 传入的参数x声明类型是X,编译器会匹配最贴合的方法签名——也就是print(X)。因为编译阶段只看参数的声明类型,不会考虑运行时的实际对象类型,所以直接把要调用的方法签名锁定为print(X)。

第二步:运行时执行重写的方法(动态绑定逻辑)

编译阶段确定了要调用print(X)之后,运行时才会去看x实际指向的对象类型(也就是Y)。因为Y类重写了X的print(X)方法,所以最终会执行Y类里的print(X)实现,输出yx。

为什么没调用Y.print(Y)?

一句话总结:重载是编译时决定的,重写是运行时决定的。
你看到x.getClass()返回Y,这是对象的实际类型,但这个信息只影响重写方法的选择,不影响重载方法的签名匹配。编译阶段已经把方法签名定死是print(X)了,运行时只会找这个签名的重写版本,不会再去匹配print(Y)。

如果想让它调用Y.print(Y),你可以把参数强制转为Y类型:

x.print((Y)x); // 此时编译时参数类型是Y,会匹配print(Y),运行时输出yy

内容的提问来源于stack exchange,提问作者Zoltán Vári

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:14:19