0
假設我們有:當「Fish f = new BlueFish();」時會發生什麼?
1 public class DynamicDispatch {
2 public static void main(String[] args) {
3 Fish f = new BlueFish();
4 f.speak();
5 }
6 }
7
8 abstract class Fish {
9 abstract String speak();
10 }
11
12 class BlueFish extends Fish {
13 String speak() {
14 return "I am a blue fish";
15 }
16 }
17
18 class CatFish extends Fish {
19 String speak() {
20 return "I am a cat fish";
21 }
22 }
問題:
從組件,青魚對象的創建。但爲什麼
javac
沒有意識到應該調用BlueFish.speak()
?在運行期間,JVM如何處理
invokespecial #4
,以便調用正確的目標?
僅供參考,javap -c
輸出爲:
Compiled from "DynamicDispatch.java"
public class DynamicDispatch extends java.lang.Object{
public DynamicDispatch();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class BlueFish
3: dup
4: invokespecial #3; //Method BlueFish."<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #4; //Method Fish.speak:()Ljava/lang/String;
12: pop
13: return
}
您可以編譯它並查看生成的字節碼... –
對象實例具有在運行時查找的虛擬方法表。該表是在實例化對象時構建的,因此特定於對象的類型。 Javac不需要知道對象類型是什麼就是從表中選擇方法編號4。 – BevynQ
@BevynQ你能指出一些有關Java的虛擬方法表的參考嗎?謝謝! – JackWM