[英]Java Interfaces
JVM使用的虛擬表解析策略是什么意思? 有人可以詳細解釋嗎?
基本上,任何未聲明為final
都可以在任何繼承的類中覆蓋。 虛擬表解析策略是Java如何動態地將方法調用分派給對象的運行時類型的方法定義。 例如,如果您有一個對象s
聲明為Shape
類型,但已實例化為new Circle()
(即Shape s = new Circle()
),然后調用s.draw()
...如果Circle覆蓋draw
,您希望調用的是Circle版本的draw方法,而不是Shape的版本。 此信息只能在運行時確定(如果您傳遞了Shape對象,則可以從編譯器從未看到過的JAR傳遞該信息,因此編譯器無法確定實例化了Shape的哪個特定子類),因此,由VM來將方法調用分派給正確的方法定義(在這種情況下,是Circle提供的draw版本)。
// Shape.java public class Shape { public void draw(){ System.out.println("I'm a Shape"); } } // Circle.java public class Circle extends Shape { public void draw(){ System.out.println("I'm a Circle"); } } // Elsewhere Shape s = new Circle(); s.draw(); // should print "I'm a Circle"
在虛擬表的大多數實現中,每個類都有一個表,其中每個條目都是成員函數及其對應的地址。 因此,Circle和Shape的虛擬表都會在“繪制”表中都有一個條目,但是Circle和Shape的虛擬表每個都具有指向該函數各自定義的繪制點條目。 然后,該類的每個實例都指向其給定類的虛擬表。 因此,當您執行new Circle()
,它包含一個指向Circle的虛擬表的條目。 調用未聲明為final
的方法時,將通過在對象的虛擬表中查找適當的偏移量來調用適當的方法實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.