2015-06-20 102 views
3

我們知道靜態綁定發生在私有,靜態,最終和重載方法上,而動態綁定發生在重寫方法上。 但是,如果我的方法只是公開的,它不是靜態的,也不會被重載和重載。靜態綁定和動態綁定用例

public class Test{ 
    public void print(){ 
     System.out.println("hello!"); 
    } 
    public static void main(String args[]){ 
     Test t = new Test(); 
     t.print(); 
    } 
} 

有人可以解釋我print()的綁定發生了什麼,因爲它既沒有超載也沒有被覆蓋。

+0

什麼是「打印」?一個方法必須總是有一個返回類型。 – CKing

+0

請注意,重載的實例方法也是動態綁定的,就像任何其他實例方法一樣。 –

+0

請注意,重載的實例方法也是動態綁定的...請問您可以用例子來解釋嗎? – user2068260

回答

1

您仍然在這裏獲得動態綁定,因爲編譯器不知道該方法沒有覆蓋。即時編譯器可能會計算出來並優化調用,但就Java編譯器而言,與方法print()的綁定是動態的。

+1

請注意,即使編譯器知道它沒有覆蓋(因爲該方法是最終的),如果最後的方法稍後變爲非最終方法,仍然會有動態綁定。 –

0

您將獲得動態綁定。實際調用的test()方法取決於不在對象的聲明類型上的對象的實際類型。在你的例子中沒有重寫它並不重要,該方法仍然是虛擬的,可以被覆蓋。

請注意,main()具有靜態綁定,因爲(作爲靜態方法)main()方法取決於類Test的實際類型。

2

無論如何,Java將使用invokevirtual來調用方法(以及動態),無論該方法是否被覆蓋。如果你看看字節代碼更清晰

public static void main(java.lang.String[]); 
Code: 
    0: new   #5     // class Test 
    3: dup 
    4: invokespecial #6     // Method "<init>":()V 
    7: astore_1 
    8: aload_1 
    9: invokevirtual #7     // Method print:()V 
    12: return 

第9行顯示invokevirtual。現在JIT編譯器可能會決定刪除動態分配以實現更好的性能,It is one of the used techniques