程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java運行時綁定探討

Java運行時綁定探討

編輯:關於JAVA

運行時綁定也叫動態綁定,它是一種調用對象方法的機制。Java調用對象方法時,一般采用運行時綁定機制。

1.Java的方法調用過程

編譯器查看對象的聲明類型和方法名(對象變量的聲明類型)。通過聲明類型找到方法列表。

編譯器查看調用方法時提供的參數類型。

如果方法是private、static、final或者構造器,編譯器就可以確定調用那個方法。這是靜態綁定。

如果不是上述情況,就要使用運行時(動態)綁定。在程序運行時,采用動態綁定意味著:虛擬機將調用對象實際類型所限定的方法。

2.運行時(動態)綁定的過程

虛擬機提取對象的實際類型的方法表;

虛擬機搜索方法簽名;

調用方法。

注意,這裡說的是對象的實際類型。即在多態的情況下,虛擬機可以找到所運行對象的真正類型。

3.在向上轉型情況下的動態綁定示例

public class Father {
  public void method() {
    System.out.println("父類方法,對象類型:" + this.getClass());
  }
}

public class Son extends Father {
  public static void main(String[] args) {
    Father sample = new Son();//向上轉型
    sample.method();
  }
}

結果1:

父類方法,對象類型:class samples.Son

這個結果沒有疑問,聲明的是父類的引用(句柄),但准確的調用了子類的對象,調用method,在子類中沒有該方法,所以去父類中尋找到並調用之。

現在修改子類,重寫(override)method方法。

public class Son extends Father {
  public void method() {
    System.out.println("子類方法,對象類型:" + this.getClass());
  }

  public static void main(String[] args) {
    Father sample = new Son();//向上轉型
    sample.method();
  }
}

結果2:

子類方法,對象類型:class samples.Son

這個結果也是意料之中的。調用method時,在子類中尋找到了該方法,所以直接調用之。

4.靜態綁定成員變量

在處理Java類中的成員變量時,並不是采用運行時綁定,而是一般意義上的靜態綁定。所以在向上轉型的情況下,對象的方法可以“找到”子類,而對象的屬性還是父類的屬性。

現在再進一步變化,在父類和子類中同時定義和賦值同名的成員變量name,並試圖輸出該變量的值。

public class Father {

  protected String name="父親屬性";

  public void method() {
    System.out.println("父類方法,對象類型:" + this.getClass());
  }
}

public class Son extends Father {
  protected String name="兒子屬性";

  public void method() {
    System.out.println("子類方法,對象類型:" + this.getClass());
  }

  public static void main(String[] args) {
    Father sample = new Son();//向上轉型
    System.out.println("調用的成員:"+sample.name);
  }
}

結果3:

調用的成員:父親屬性

這個結果表明,子類的對象(由父類的引用handle)調用到的是父類的成員變量。所以必須明確,運行時(動態)綁定針對的范疇只是對象的方法。

現在試圖調用子類的成員變量name,該怎麼做?最簡單的辦法是將該成員變量封裝成方法getter形式。

public class Father {
  protected String name = "父親屬性";
  public String getName() {
    return name;
  }
  public void method() {
    System.out.println("父類方法,對象類型:" + this.getClass());
  }
}

public class Son extends Father {
  protected String name="兒子屬性";

  public String getName() {
    return name;
  }

  public void method() {
    System.out.println("子類方法,對象類型:" + this.getClass());
  }

  public static void main(String[] args) {
    Father sample = new Son();//向上轉型
    System.out.println("調用的成員:"+sample.getName());
  }
}

結果4:

調用的成員:兒子屬性

本文出自 “子 孑” 博客,請務必保留此出處http://zhangjunhd.blog.51cto.com/113473/49452

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved