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
相关产品推荐
相关产品推荐

