方法呼叫指令invoke

2021-08-05 21:33:56 字數 2239 閱讀 7576

1、方法呼叫(分派、執行過程):

jvm呼叫方法有五條指令,分別是

(1)invokestatic,用來呼叫static方法(類方法)

(2)invokespecial,用來呼叫需要特殊處理的例項方法,私有方法,父類方法(super.),初始化方法。在物件的建立過程中,new之後很多都會執行方法,就是依賴位元組碼中是否包含invokespecial指令。靜態繫結

(3)invokevirtual,用於呼叫物件的例項方法,根據物件的實際型別進行分派(虛方法分派)最常見的。動態繫結

多型例子

(4)invokeinte***ce,呼叫介面方法,在執行時搜尋乙個實現了這個介面方法的物件,找出適當的方法進行呼叫。

(5)invokedynamic。方法動態解析出呼叫點限定符所引用的方法

方法呼叫指令與資料型別無關,但是方法的返回指令與返回的資料型別相關。

這篇文章主要是說明invokevirtual方法的呼叫,以乙個例子來說明。

package t2_p3;

class father

private void fme1()}

class son extends father}

public class main

}

父親

父親:fme1

t2_p3.son@15bdc50

父親:fme1

父類father中有乙個public方法fme()和乙個私有方法fme1(),子類中沒有對其方法覆蓋。father test = new son();,並呼叫fme(),再在fme()中呼叫自己的私有方法fme1()。

方法呼叫中test.fme()是invokevirtual呼叫,編譯時指向父類的fme(),在執行時由於是invokevirtual呼叫,因此test將變成實際型別son,如果son中有fme(),就呼叫son自己的,若沒有就呼叫父類的,此時是呼叫父類的;在父類中 的fme1()是invovespecial呼叫。上面的this代表son,既然是invovespecial呼叫,但呼叫的不是son的fme1(),而是呼叫父類的fme1()。

上面的用this呼叫的時候,我覺得在編譯期間,this代表的是father類,而不是son類,正因為是這樣,在用invovespecial位元組碼呼叫的時候採用在編譯器就確定好了指向父類fme1()方法,而不是子類的方法。為了確定我說的,我採用了兩種方式去驗證:1是用myeclipse的動態提示,2是將fme1()方法

改為public,這樣在位元組碼指invokevirtual呼叫的時候看是不是在執行期間改變this為實際型別son類,即是不是去呼叫子類的fme1()方法。

1:我在myeclipse

中用提示鍵得到如下,可以看出只有父類的兩個方法,並沒有子類son的方法。

2、在我將fme1()方法改為public

後確實是呼叫的是子類的方法。

package t2_p3;

class father

public void fme1()}

class son extends father}

public class main

}

父親兒子fme1

t2_p3.son@15bdc50

兒子fme1

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

Method的Invoke方法,呼叫失敗注意點

從父類class通過getdeclaredmethod獲取的method可以呼叫子類的物件,而子類改寫了這個方法,從子類class通過getdeclaredmethod也能獲取到method,這時去呼叫父類的物件也會報錯。public class classa public class classb...

JVM方法呼叫指令

終於把inside jvm這本看完了,好久沒這麼細緻的看一本書了。好多人都寫了文章討論jvm如何實現多型的,我只是簡單做個筆記。類的位元組碼結構有個常量池,其中就存放了這個類中呼叫的方法的符號引用,這些符號引用實際上是放在一些特殊型別 constant nameandtype info 的常量池入口...

php魔術方法 invoke

php5.3新增了乙個叫做 invoke的魔術方法,這樣在建立例項後,可以直接呼叫物件。就是用函式的方式來用物件,比如我現在有個a類,如果我想防止別人直接輸出物件,那麼我可以這樣 class a a new a echo a 那麼就會輸出 不允許這樣使用 invoke 方法,也可以,帶引數 clas...