2011-12-01 49 views
6

我現在專注於需要洞察Java字節碼的項目。如何識別Java字節碼中的覆蓋方法?

bcel的幫助下,我現在可以完成大部分工作。有一點,我現在不清楚如何識別子類方法覆蓋其基本代碼?在指示此重寫關係的方法中是否存在與.class文件關聯的任何屬性,還是應該向後返回其基類可以比較方法簽名?

任何提示將不勝感激。

回答

5

您需要查看層次結構鏈 - 字節碼中沒有任何內容表明它是重寫的方法,因爲不需要。

+0

爲什麼沒有必要?那麼JVM如何動態鏈接不同的'.class'文件呢?它是否自下而上搜索固有的層次結構,直到找到匹配的方法爲止?謝謝。 –

+1

@Summer_More_More_Tea翻轉問題 - 爲什麼*有必要?如果它是您正在查看的課程的一種方法,爲什麼虛擬機需要知道它被覆蓋? –

+0

@ DAVE聽起來很贊。:)謝謝。 –

-1

您可以對其進行反編譯並將代碼作爲您選擇的IDE中的項目加載。通常,您可以輕鬆地跳轉到繼承類的重寫方法。

+0

感謝您的快速響應。但是如何用Java代碼實現這一點? :) –

2

如果你不能依賴於@Override屬性,那麼看起來根據the spec,只需要看類就沒有別的辦法。我認爲你需要看看超類。

+4

'@ Override'具有[SOURCE](http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/annotation/RetentionPolicy.html#SOURCE)保留。 –

+0

@DᴀᴠᴇNᴇᴡᴛᴏɴ:謝謝。 – opqdonut

+0

@ DAVE +1。也感謝opqdonut的回覆。 –

2

不幸的是,你不能從字節碼中知道。註釋@Override只是一個建議性的 - 它不是強制性的。

JVM定義了5種調用方法的方法。它們是invokevirtual,invokeinterface,invokespecial,invokestatic和新的invokedynamic。

關注invokevirtual - 這是最常見的調度形式,並且是您在此處討論的情況下使用的一種。

invokevirtual的工作方式是在運行時查看要分派的對象的類。如果它找到了我們之後的方法的實現,那麼它會調用它。如果不是,那麼它會查看對象類的超類並再次嘗試,等等。

因此,沒有辦法從字節碼中可靠地判斷給定的方法是否被覆蓋,而無需查看父類的字節碼。

0

編譯後生成字節碼。因此,它只假定基於引用變量調用的方法,因爲該對象尚未創建。