2014-03-13 46 views
8

我已經搜索了關於堆棧溢出的後期綁定的所有類似問題,並且我會嚴重不同意將這個問題標記爲重複的任何人。首先,我在另一個問題上找到了這個例子,但是我不明白在編譯期間何時決定什麼時候以及何時在運行時決定什麼時我應該知道該怎麼做。基本上,我的問題的癥結歸結爲兩點:Java中的後期綁定

  • 在什麼這個例子必須帶我到邏輯結論,一個方法是後期綁定而另一個早期綁定

  • 如何我知道什麼時候決定哪些執行方法的版本在運行時決定或編譯時在Java中

代碼:

class A 
{ 
    public void foo() 
    { 
     System.out.println("Class A"); 
    } 
} 

class B extends A 
{ 
    public void foo() 
    { 
     System.out.println("Class B"); 
    } 
} 

public class C 
{ 
    public static void main(String [] args) 
    { 
     A a=new A(); 
     B b=new B(); 
     A ref=null; 

     /* 
      early binding --- calls method foo() of class A and 
      decided at compile time 
     */ 
     a.foo(); 

     /* early binding --- calls method foo() of class B and 
      decided at compile time 
     */ 
      b.foo(); 

     /* late binding --- --- calls method foo() of class B and 
      decided at Run time 
    */ 
     ref=b; 
     ref.foo(); } 
} 
+0

最後的靜態或私有方法不會發生後期綁定。對於任何其他它確實如此。就這些。 – Pshemo

+3

給未來讀者的提示:上面代碼中的註釋不正確! –

+1

如果我的回答很有幫助,您可以請修改意見然後 – user3163829

回答

2

Java對所有非最終非私有實例方法使用後期綁定。這就是多態如何實現的。您評論的所有電話都是在運行時確定的。

A a=new A(); 
a.foo(); 

a所引用的對象A這樣A的實現將被發現,結合並使用。

B b=new B(); 
b.foo(); 

b被引用對象B所以B的實現將被發現,約束,和使用。

ref=b; 
ref.foo(); 

ref被引用對象B所以B的實現將被發現,約束,和使用。

該變量的靜態(聲明)類型僅供編譯器用來驗證此類方法是否可訪問。

相關:

6

錯誤在所有計數。要調用的方法是在運行時決定的,這裏的每種情況都是基於對象的運行時類型。在編譯時做出的唯一決定是調用final,private或static方法,或者在一組重載方法中進行選擇(如果重載方法不是最終的,私有的或靜態的,這仍然會導致運行時選擇。)

0

考慮語句

A ref; //reference of A 
    ref = new B();//Object of B 
     ref.f2(); 

這裏裁判是的class A參考並且其具有的class B F2(對象的地址)是overridden方法。

當編譯器檢測到這樣的語句時,它不會將函數調用與任何定義綁定。它只驗證呼叫。

這些調用的綁定留給運行時環境。在程序運行時,系統識別對象的數據類型,並將函數調用與對象類提供的函數定義綁定。函數調用和函數定義之間的這種類型的綁定稱爲「後期綁定」或「運行時綁定」或「運行時多態性」或「動態方法分派」。

通過this question and read my answer例子也在那裏給出。

0

當你在任何對象上調用一個方法時,總會記住在繼承中調用方法的「最少修改版本」。這只不過是從層次結構中動態選取方法版本。

1

這裏的所有答案大部分是正確的,但是關於Java中後期綁定有一個關鍵點缺失。
如果我們通過後期綁定的定義,Java不會執行「通過本書」後期綁定。 其書本定義表單中的後期綁定意味着編譯器不應執行參數檢查,對方法調用不進行類型檢查,並且應該將其全部留給運行時 - 因爲編譯器可能無法訪問方法實現代碼(例如在COM編程中)。 然而,Java在編譯時確實會驗證,即使是在一個多態的場景中,被調用的方法和方法簽名確實存在於表達式的類型層次結構的某處,從而使該方法有效。因此,例如,可以說,我請裁判的方法foo1不在A或B存在:

A ref=null; 
ref=new B(); 
ref.foo1(); 
//This will not compile in Java, because java will check at compile time 
//for the method foo1 in the type hierarchy of A, which is the type of the 
// variable ref at compile time. 
//In pure late binding, however this would pass compilation and 
//throw an error at runtime. 

後期綁定方案中,所述的方法foo1()是否存在的確定或沒有正確的參數數量純粹在運行時。 但是在Java中,在編譯時會進行一定程度的檢查,以確保具有正確數量參數的方法確實存在於類型層次結構中的某處。
我認爲Java執行的唯一時間純粹的後期綁定是如果使用反射來調用方法的。 Java所做的最好稱爲動態調度而不是後期綁定,但是所有人都稱它爲Java後期綁定,因此存在混淆。