2012-04-19 38 views
4

我學習了很多關於C++如何在存在繼承(多重,虛擬等)的情況下管理其虛擬表以及它如何在內存中放置對象的方法。Java方法表

現在,Java只需要擔心單行繼承,沒有實例方法隱藏等,所以在這種情況下虛擬表應該更簡單一些。我知道Class文件充當方法區域的「網關」,其中存儲了類型定義,包括方法字節碼I推測。我想到以下兩個問題:

  1. Java中有沒有任何vtable/method表結構?它如何存儲並鏈接到Class對象?
  2. 繼承/動態方法調用如何解決?我的意思是:

具有以下類和實例:B中

class A{ int f(){...} } 
class B extends A{ int f(){...} } 

A a = new B(); 
a.f(); 

F()被調用。 B通過Class文件解析正確的方法指針?

非常感謝您的意見。

回答

3

a.f()該呼叫被在Java字節碼彙編語言爲實現。 但正如您所看到的,類格式非常抽象,並且JVM可以自由地爲「高效」實現加載類。

+0

當然。我認爲解決方案在運行時會使用B的'Class'文件並從那裏加載方法,這就是爲什麼B.f()被調用 – Bober02 2012-04-19 10:34:35

3

Here是一個相關的問題,其中包含正確的鏈接。有一件事需要注意,這在我引用的SO問題中沒有明確表達,即Java中的所有方法都是隱式虛擬的。如果對技術細節感興趣,請查看jvm.h(搜索字符串「vtable」)。

3

在Java中,只有指定它必須做的事情,它是如何做的不是。這有一些優點,可以通過C++不允許的方式對代碼進行優化。例如,即使虛擬機來自不同的庫/ jar,「虛擬」方法也可以由JVM內聯。

aload_1 // load the local variable a, here from local address 1 
invokevirtual with index into the constant pool for 
    method ref: 
     class "A" 
     nameAndType "f", "()I" 

在運行時可能V表然後解決調用B.f():

+0

好的,你知道的任何可能的解決方案都是成功的嗎? SUN如何做到這一點? – Bober02 2012-04-19 10:04:05

+1

我會說a)你不需要知道b)它可以在任何時候改變,所以你不會想要在某個特定的實現上建立一個解決方案。在C++編譯完代碼後,你知道它不會改變,但在Java中並非如此,甚至在程序運行時也會改變。 – 2012-04-19 10:06:34