动态绑定实现机制
java中多态更多的是指父类调用子类的引用。
Java虚拟机在调用一个类方法时,它会基于对象引用的类型(通常子啊编译时可知)来选择所调用的方法。相反,当虚拟机调用一个实例方法时,它会基于对象实际的类型(只能在运行时得知)来选择所调用的方法,这就是动态绑定。
动态绑定内部机制
方法表是一个指向方法区中的方法指针的数组。方法表中不包含static、private等静态绑定的方法,仅仅包含那些需要动态绑定的实例方法。 在方法表中,来自超类的方法在来自子类的方法之前,并且排列方法指针的顺序和方法在class文件中出现的顺序相同,这种排列顺序的例外情况是,被子类的方法覆盖的方法出现在超类中该方法第一次出现的地方。 例如有超类Base 和 子类Derive
public class Base{
public Base(){}
public void test(){
System.out.println("in Base");
}
public void print(){}
}
public class Derive extends Base{
public Derive(){}
public void test(){
System.out.println("in Derive");
}
public void sayHello(){}
public static void main(Stirng[] args){
Base base = new Derive();
base.test();
}
}
在Base方法表中,test()指针指向的是Base的test()方法内存地址。在Derive方法表中,test()指针指向的是Derive 的test() 方法的内存地址。
那jvm虚拟机是怎么知道base是哪个具体的实例呢?根据对象模型可以看出,虚拟机从对象内存中的第一个指针“特殊结构指针开始”,可以找到实际对象的类型数据和Class实例,这样虚拟机就可以知道base引用的实际对象是Derive对象。在往下找就是test()指针,而这个指针指向的是Derive的test()方法的内存地址,所以执行Derive的test()方法。
这是动态绑定的一种实现方式,根据不同的JAVA虚拟机平台和不同的实际约束,动态绑定可以有不同的内部实现机制。
参考陶邦仁博客