2012-09-15 26 views
1

我已經在多個地方閱讀了最終方法是早期綁定但沒有提供令人滿意的理由。我懷疑即使在父類引用的最後一個方法中,它也不能如此,因此編譯器不能說是否調用了父類的非final或child的最終方法。
請指教。在最終方法中的早期綁定

class Parent { 
    void meth() { 
     System.out.println("parent"); 
} 
} 

class Child extends Parent { 

@Override 
final void meth() { 
    // TODO Auto-generated method stub 
    System.out.println("child"); 
} 

public static void main(String[] args) { 
    Parent parent = new Parent(); 
    Parent child = new Child(); 
    child.meth(); 
    parent.meth(); 
} 
} 

在上面的代碼方法甲基()稱爲兒童(父參考)是一種最終方法,但那麼JVM應該需要使用一個方法查找表在運行時作爲在其孩子或父方法被調用。

+1

如果該方法是最終的,那麼JVM就不需要在運行時使用方法查找表,所以它很有意義,因爲它很早就綁定了。 –

+0

你的問題是什麼?此代碼按照您的預期輸出「孩子父母」,不是嗎? – Eric

回答

1

java中的綁定發生在兩個階段。在編譯時,編譯器已知的引用類型用於將該方法綁定到最高方法的類型層次結構上。例如。如果在Number類型變量上調用toString(),則編譯器知道它必須調用Number.toString()或子類重寫而不是Object.toString()。

其次,在運行時調用方法時,會查看對象的運行時類型,並找到並調用類型層次結構中最具體的方法。即在上面的Number.toString的情況下,如果對象是一個Integer,它會找到Integer.toString並調用它。

如果方法在參考/變量的類型中是最終的,那麼可以跳過第二步,因爲我們知道不會有子類覆蓋。這就是Dima Rudnick所說的靜態類型。再次以我的示例爲例,如果Number.toString是final,並且變量的類型爲Number,那麼我們不需要查看運行時類型以知道我們調用的是什麼方法。

注意:爲了這個目的,我假設Object,Number和Integer都有一個特定的toString方法,而不是依賴於繼承的方法。

3

當然,只有當引用的靜態類型是方法具有最終說明符的類時,纔會發生早期綁定。

+0

請詳細說明 – user1649415

+4

上面給出的代碼的確是一種您無法進行早期綁定的情況。然而,如果'meth'在'Parent'中是'final',那麼即使有子類,也可以在調用'meth'時進行早期綁定 - 因爲'Child'不能覆蓋'meth'。 –

相關問題