1. 程式人生 > >jvm原理(34)虛方法表與動態分派機制詳解

jvm原理(34)虛方法表與動態分派機制詳解

編寫程式碼:

public class MyTest7 {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Animal dog = new Dog();

        animal.test("hello");
        dog.test(new Date());
    }

}

class Animal{
    public void test(String str){
        System.out.println("animal str"
); } public void test(Date date){ System.out.println("animal date"); } } class Dog extends Animal{ @Override public void test(Date date) { System.out.println("dog date"); } @Override public void test(String str) { System.out.println("dog str"
); } }

執行結果:

animal str
dog date

方法表: 針對方法呼叫動態分派的過程,虛擬機器會在類的方法區建立一個虛擬方法表的資料結構(virtual method table,vtable), 針對於invokeinterface指令來說,虛擬機器會建立一個叫做介面方法表的資料結構(interface method table,itable)

方法表會在類的連線階段初始化,方法表儲存的是該類方法入口的一個對映,比如父類的方法A的索引號是1,方法B的索引號是2。。。 如果子類繼承了父類,但是某個父類的方法沒有被子類重寫,那麼在子類的方法表裡邊該方法指向的是父類的方法的入口,子類並不會重新生成一個方法,然後讓方法表去指向這個生成的,這樣做是沒有意義的。還有一點,如果子類重寫了父類的方法,那麼子類這個被重寫的方法的索引和父類的該方法的索引是一致。比如父類 A的test方法被子類C重寫了,那麼子類C的test方法的索引和父類A的test方法的索引都是1(打個比方),這樣做的目的是為了快速查詢,比如說在子類裡邊找不到一個方法索引為1的方法,那麼jvm會直接去父類查詢方法索引為1的方法,不需要重新在父類裡邊遍歷。