public class test2 {
static class Father {
public int money = 1;
public Father() {
money = 2;
showMeTheMoney();
}
public void showMeTheMoney() {
System.out.println("I am Father, i have $" + money);
}
}
static class Son extends Father {
public int money = 3;
public Son() {
money = 4;
showMeTheMoney();
}
public void showMeTheMoney() {
System.out.println("I am Son, i have $" + money);
}
}
public static void main(String[] args) {
Father guy = new Son();
}
}
这段代码输出为
为什么会是这个输出,我希望大佬们能通过字节码指令的方式教教我。
这是我得到的main方法的字节码指令,我也查看了Son与Father的init方法的字节码指令。大概流程是main->new Son -> Son init -> Father init - > Father showMeTheMoney -> Son showMeTheMoney。不知道这个流程对不对。
《深入理解JAVA虚拟机 第三版》周志明著中写道invokevirtual是调用对象实例的方法,我很想知道在为什么他会调用Son的showMeTheMoney,他传的对象实例都是Son吗?
由于Java是动态绑定的,所以是根据对象的实际类型(
Son
)来决定调用哪个方法。所以即使是在Father
的构造函数中调用showMeTheMoney()
,最终执行的是Son
中的实现。而且在
Father
的构造函数中,Son
对象的money
属性还没有初始化所以输出i have $0
。你的字节码应该是对的