为何重载方法接收声明为Number的Integer实例时,执行Number版本?
为什么你的Java代码输出是"Number"而不是"Integer"?
这问题我当初刚学Java的时候也踩过坑!咱们一步步拆解清楚:
核心原因:这是方法重载的静态绑定,而非多态的动态绑定
你这里的两个met方法是方法重载(overload)——方法名相同,但参数类型不同;而Java多态(运行时动态绑定)对应的是方法重写(override)——子类重写父类的同名同参方法,二者逻辑完全不同。
编译阶段就确定了调用哪个方法
在Java中,方法重载的调用是编译时静态绑定的,编译器只看变量的声明类型,不看实际运行时的对象类型:
- 你的变量
x的声明类型是Number,虽然它实际指向的是Integer对象,但编译器在编译met(x)这行代码时,只会根据x的声明类型Number去匹配最合适的重载方法。 - 这里两个重载方法:
met(Integer i)和met(Number i),Number类型的参数无法直接匹配Integer类型的形参(因为Integer是Number的子类,赋值方向是子类→父类,反过来不成立),所以编译器会选择参数类型为Number的那个方法。
那什么时候会触发多态的动态绑定?
如果是方法重写的场景,才会触发多态的运行时动态绑定,比如:
class Parent { void met() { System.out.println("Parent"); } } class Child extends Parent { @Override void met() { System.out.println("Child"); } } public class Test { public static void main(String[] args) { Parent p = new Child(); p.met(); // 这里会输出"Child",这才是多态的动态绑定,运行时看实际对象类型 } }
这种情况下,运行时才会根据对象的实际类型来决定调用哪个方法,也就是你预期的多态机制。
总结一下:你的代码用的是方法重载,编译时就确定了调用met(Number i),所以输出"Number",这和多态的动态绑定不是一回事~
内容的提问来源于stack exchange,提问作者energize-cactus
相关产品推荐
相关产品推荐

