2015-11-06 81 views
0

我有一個關於動態與靜態的簡單問題。所以從我讀過的內容來看,靜態綁定是針對私有的,最終的,重載的靜態方法,它依賴於引用的類型。動態是例如方法不是私有的,最終的,重載的並且依賴於對象的類型。Java動態與靜態綁定

如果你這樣做Human myobj = new Boy();,這是引用類型和它是對象的類型?

+2

因此......您認識到靜態和動態綁定適用於*方法*,但隨後詢問有關對象和引用的內容? –

+0

我不是專家,但我相信你的例子也是靜態的。所有信息都可以在編譯時使用,所以編譯器應該能夠執行所有必要的檢查。引用的類型是「人」,對象的類型是「男孩」,就像它在錫上說的一樣。 – markspace

回答

1

靜態的Java綁定,而動態綁定運行期間發生,所以你的類型是人與物體的類型(如果你做例如的instanceof)將男孩在編譯時有發生。

2

你的說法是不正確有關final和超載。不知道你讀到哪裏。

使用Java 8(1.8.0_51)編譯以下代碼。

public class Test { 
    public static void main(String[] args) { 
     Test x = new Test(); 
     x.a(); 
     x.b(); 
     x.c(); 
     x.d(1); 
     x.d(1L); 
     x.d(1d); 
     x.d(null); 
    } 
    private  void a() {} 
    public final void b() {} 
    public static void c() {} 
    private  void d(int x) {} 
    public final void d(long x) {} 
    public static void d(double x) {} 
    public  void d(String x) {} 
} 

注意:使用實例變量調用靜態方法是不好的形式。應該使用類名完成,因此顯式靜態。代碼使用實例變量僅用於說明目的。

反編譯的字節碼顯示:

0: new   #1     // class test/Test 
    3: dup 
    4: invokespecial #19     // Method "<init>":()V 
    7: astore_1 
    8: aload_1 
    9: invokespecial #20     // Method a:()V 
    12: aload_1 
    13: invokevirtual #23     // Method b:()V 
    16: invokestatic #26     // Method c:()V 
    19: aload_1 
    20: iconst_1 
    21: invokespecial #29     // Method d:(I)V 
    24: aload_1 
    25: lconst_1 
    26: invokevirtual #33     // Method d:(J)V 
    29: dconst_1 
    30: invokestatic #36     // Method d:(D)V 
    33: aload_1 
    34: aconst_null 
    35: invokevirtual #39     // Method d:(Ljava/lang/String;)V 
    38: return 

private方法a()d(int)專門調用。
static方法c()d(double)靜態調用。
其餘的方法b()d(long)d(String)幾乎被調用。

正如你所看到的,final和超載不影響結果。

invokestatic文檔:

調用一個類別(靜態)方法

invokespecial文檔:

調用實例方法;特殊處理的超類,私人,和實例的初始化方法調用

invokevirtual文件:

調用例如方法; 調度基於上類

「調度基於」是指動態綁定,其他兩個是靜態綁定。

還有兩個調用指令:

  • invokeinterface:像invokevirtual但接口的參考,而不是類引用。
  • invokedynamic:主要用於動態(腳本化)語言,例如Groovy和「通過執行invokevirtual指令來調用」。