在java语言的实现机制中,需要对函数名与具体函数进行绑定(binding),而在调用之前需要对已经绑定好的函数进行分派(dispatch)。
我们接下来具体讨论绑定和分派的机制。
绑定是将函数名与具体函数代码进行关联的过程。
由于java语言的多态特性,绑定分为两种:
1.提前/静态绑定(Early/static binding)
提前绑定用于绑定带有static,private,final关键字的函数,由以上任意之一修饰符的函数就会使用提前绑定。事实上只要不发生override现象都会使用提前绑定。提前绑定在编译阶段完成。
2.延迟/动态绑定(Late/dynamic binding)
延迟绑定用于绑定发生override现象的函数,即某一函数在父类和子类中都有出现,名称相同参数相同返回值相同。延迟绑定在编译阶段完成。
分派是决定在执行阶段究竟执行哪一段代码的过程。
分派亦分为两种:
1.静态分派(static dispatch)
静态分派针对一一对应的绑定,如果绑定时没有遇到多态现象,函数名只针对一段代码,那么就可以直接在编译阶段将代码分派好。这个过程在编译阶段执行。
2.动态分派(dynamic dispatch)
动态分派针对非一一对应的绑定,如果有一个函数名绑定了多段代码,那么就需要在运行阶段才能知道该分派那段代码给该函数名。这个过程在运行阶段执行。
让我比较混乱的一件事是动态分配之前可能是提前绑定也可能是延迟绑定。
因为如果发生了overload就会调用提前绑定和动态分配。如果发生了override就会调用延迟绑定和动态分配。
但如果发生了延迟绑定那么就一定会是动态分配。
我查阅了一些其它的文章,很多人只提到了java中的binding而没有dispatch。接着我去看了Wikipedia,我发现上面的内容和我上课的ppt上是一样的。。。。并没有新的东西。
按照我的猜想,可能这样的机制是一开始的设计,但java在实现的过程中将之简化了,统一成了binding,绑定的过程也就包括了分派。
但wikipedia上特意指出binding不等于dispatch,先写到这,等我有了更深的理解再继续写。
另外我仿佛明白了上课的ppt上的部分内容是怎么来的了。。。我觉得把wiki上的东西搬到ppt上是很不专业的。很多人看到出处是wiki的引用,脸色就会变得很难看。这真的不太好。