invokevitual指令的疑惑?

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();
    }
}

这段代码输出为
image.png
为什么会是这个输出,我希望大佬们能通过字节码指令的方式教教我。

image.png
这是我得到的main方法的字节码指令,我也查看了Son与Father的init方法的字节码指令。大概流程是main->new Son -> Son init -> Father init - > Father showMeTheMoney -> Son showMeTheMoney。不知道这个流程对不对。
《深入理解JAVA虚拟机 第三版》周志明著中写道invokevirtual是调用对象实例的方法,我很想知道在为什么他会调用Son的showMeTheMoney,他传的对象实例都是Son吗?

阅读 264
1 个回答

由于Java是动态绑定的,所以是根据对象的实际类型(Son)来决定调用哪个方法。所以即使是在Father的构造函数中调用showMeTheMoney(),最终执行的是Son中的实现。
而且在Father的构造函数中,Son对象的money属性还没有初始化所以输出i have $0

你的字节码应该是对的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏