package demo.jvm.test8? public /** * 方法动态分派演示 * */ static protected System.out.println("Human say hello")? }? } static protected System.out.println("man say hello")? } } static protected System.out.println("woman say hello")? } } public Human man = new Human woman = new man.sayHello()? woman.sayHello()? man = new man.sayHello()? } } 结果: |
man say hello woman say hello woman say hello package public /** * 方法动态分派演示 * */ static protected System.out.println("Human say hello")? }? } static } static } public Human man = new Human woman = new man.sayHello()? woman.sayHello()? man = new man.sayHello()? } } 结果: Human say hello |
Human say hello Human say hello
由于invokevirtual指令执行的第一步就是在运行期确定接收者的实际类型,所以两次调用中的invokevirtual指令把常量池中的类方法符号引用解析到了不同的直接引用上,这个过程就是Java语言中方法重写的本质。我们把这种在运行期根据实际类型确定方法执行版本的分派过程称为动态分派。
所以重载之和传入的变量有关系,重写却以子类为基准,越底层的子类权限越大。
注意这里首先动态分派调用的时候会先调用子类的方法,如果子类找不到则找父类,父类找不到则找父类的父类,如果到最后都找不到抛异常(一般情况下这种找不到的情况在编译器就会跑出来了。)
原文地址:https://www.cnblogs.com/qingruihappy/p/9691688.html