方法调用-单分派多分派

/ Jvm / 没有评论 / 388浏览

在前两篇中我们主要介绍了静态分派和动态分派的功能,在这一篇中我们主要分享一下单分派和多分派的知识。单分派和多分派主要是按方法的宗量区分的,那什么是方法的宗量?什么是单分派?什么是双分派呢? 我们看下面它们的定义。

方法的宗量:方法的接收者与方法的参数统称为方法的宗量。

单分派:是根据一个宗量对目标方法进行选择的。

多分派:是根据一个以上的宗量对目标方法进行选择的。

以上定义确实是比较难理解的,我们还是采用和静态分派和动态分派一样,先看一下具体代码,然后在做详细分析。

public class Dispatch {
static class QQ {
}

static class YY {
}

public static class Father {
public void hardChoice(QQ arg) {
System.out.println("Father QQ");
}

public void hardChoice(YY arg) {
System.out.println("Father YY");
}
}

public static class Son extends Father {
public void hardChoice(QQ arg) {
System.out.println("Son QQ");
}

public void hardChoice(YY arg) {
System.out.println("Son YY");
}
}

public static void main(String[] args) {
Father father = new Father();
Father son = new Son();
father.hardChoice(new YY());
son.hardChoice(new QQ());
}
}
Father YY
Son QQ

源码中我们首先创建了两个对象然后调用了它们所属对象的hardChoice()方法。所以在上述代码中首先执行的是静态分派过程,也就是由编译器执行的。上述的静态分派过程的目的就是选择要执行的目标方法,也就是需要选择是执行Father中的方法还是Son中的方法。按照静态分派的规则是通过参数的静态类型而不是实际类型作为判定依据的。 也就是通过所属对象来确定方法的选择的。在程序执行时虚拟机还会根据执行的参数来确定重写的方法版本也就是QQ还是YY。  因为上述的选择是根据两个宗量进行的,所以静态分派属于多分派

下面我们在分析一下上述的代码的动态分派过程,也就是由虚拟机选择的。 在执行下面的代码时

son.hardChoice(new QQ());

因为编译器已经确定了目标方法的名称,也就是

hardChoice(QQ arg)

方法,所以虚拟机此时在执行时不会在做任何选择,而是直接执行编译器选择好的目标方法。但也有一个因素会影响虚拟机的执行。也就是此方法的接受者的实际类型是Father还是Son。 因为只有一个宗量作为选择,所以动态分派属于单分派

所以Java语言可以理解为是一种静态多分派、 动态单分派的语言。