Java静态分派与动态分派_静态分派与动态分派——记一次被腾讯面试官暴虐的面试经历 - wunsiang - 博客园...

在腾讯的面试中被问到了重载的运行时多态是怎么实现的,显然这一块是我的知识盲区,所以赶紧补充下。

静态分派

依赖静态类型来定位方法执行版本的分派动作称作静态分派,静态分派的典型是方法重载。如下代码实例:

public class StaticDispatch {

static abstract class Human {

}

static class Man extends Human {

}

static class Woman extends Human {

}

public void sayHello (Human guy) {

System.out.println("hello,guy");

}

public void sayHello (Man guy) {

System.out.println("hello,gentleman");

}

public void sayHello (Woman guy) {

System.out.println("hello,lady");

}

public static void main(String[] args) {

Human man = new Man();

Human woman = new Woman();

StaticDispatch sr = new StaticDispatch();

sr.sayHello(man);//hello,guy!

sr.sayHello(woman);//hello,guy!

}

}

对于这段代码的运行结果想必大家都很清楚,究其原因,重载的方法调用是由静态类型而非实际类型决定的,在编译器便决定了使用哪个重载版本,并会把这个方法的符号引用写到main()方法的两条invokevirtual指令的参数中。

总结:Java重载是基于静态分派完成的。

动态分派

我们知道Java多态性另一种实现方式是“重写”,而这种运行时多态编译器是不可能知道它的实际调用的实例的,如下代码所示:

Scanner in = new Scanner(System.in);

Person person = null;

if (in.nextLine().equals("chinese")) {

person = new Chinese();

} else {

person = new English();

}

person.sayHello();

在重载的场景下,JVM使用的是动态分派,即在运行时确定接受者的实际类型。JVM会在操作数栈中找到指向对象的实际类型,之后在该类的方法表(存在方法区中,存放着各个方法的实际入口)中找到对应描述符和和简单名称都相符的方法,同时进行访问权限校验,如通过则查找过程结束。如果没有找到匹配的方法,则通过继承关系在该类的父类的方法表中查找,查找到则结束,否则抛异常。

参考资料

多态在 Java 和 C++ 编程语言中的实现比较

《深入理解Java虚拟机》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值