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...