根据分派基于多少种宗量(方法的接收者与方法的参数统称为方法的宗量),可以将分派划分为单分派和多分派两种。单分派是根据一个宗量对目标方法进行选择,多分派则是根据多余一个宗量对目标方法进行选择。
单分派和多分派的定义读起来拗口,从字面上看也比较抽象,下面通过一个例子来具体看一下。
运行输出
father choice 360
son choice QQ
在main函数中两次调用hardChoice方法,这两次的结果输出如上。
我们来看看编一阶段编译器的选择过程,也就是静态分派的过程。这时选择目标方法的依据有两点:一是静态类型是father还是son,二是方法参数是QQ还是360.这次选择的最终结果产物是产生了两条invokevirtual指令,两条指令的参数分别为常量池中指向father.hardChoice(360)和Father.hardChoice(qq)方法的符号引用。因为是根据两个宗量进行选择所以Java语言静态分派属于多分派。
再看看运行时虚拟机的选择,也就是动态分派过程,在执行“son.hardChoice(QQ)”这句代码时,更准确的说,是执行这句代码所对应的invokevirtual指令时,由于编译期已经决定目标方法的签名必须为hardChoice(QQ),虚拟机此时不会关心传递过来的参数QQ到底是腾讯的还是阿里的,因为这时参数的静态类型、实际类型都对方法的选择不会构成实际影响,唯一可以影响虚拟机选择的因素只有此方法的接收者的实际类型是father还是son。因为只有一个宗量作为选择依据,所以Java的动态分派属于单分派类型。
网友评论