詳細解釋JAVA中的靜態綁定和動態綁定

總結JAVA的靜態綁定和動態綁定

 

對於繼承關係複雜的類層次結構,訪問對象的實例成員和訪問類的靜態成員,以及在對象的實例方法或類的靜態方法中訪問其它靜態成員或動態成員時,如果不搞清楚靜態綁定和動態綁定的規律,往往容易出現意想不到的結果,導致繼承關係的一組類設計失敗。

 

以下用三句話總結了動態綁定和靜態綁定的規律。

 

      在類的繼承體系中,

  • 訪問靜態成員(包括靜態方法和靜態變量)或實例變量,在調用時具體綁定哪一級的實現,完全取決於調用類的名稱,或調用對象的聲明類型定義,與實例的具體構造類型無關,即與運行時無關;
  • 訪問實例方法,在調用時具體綁定哪一級的實現,只取決於對象實例的具體構造類型,與對象的聲明類型(引用)無關;進一步,在所有實例方法的調用堆棧中,總是優先尋找對象實例的具體構造類型那一級的實現,因此,可能出現鉤子,如 B{void m2(){}} extends A{ void m1(){m2();}   void m2(){}};A b = new B(); 訪問b.m1(),則出現調用堆棧 A.m1()->B.m2()的情況,m1方法不會調用到A的m2方法實現;
  • 實例方法中訪問其它成員,包括靜態變量和實例變量,也都總是優先尋找對象實例的具體構造類型那一級的實現。如B{void m2(){m3();}  static void m3(){}} extends A{ void m1(){ m2();}   void m2(){m3();} static void m3()};A b = new B(); 訪問b.m1(),則出現調用堆棧 A.m1()->B.m2() -> B.m3()的情況;B.m2()不會調用到A定義的m3()靜態方法。

上面的話可能有些繞口,以下幾個名詞。

  • 靜態成員:包括靜態變量和靜態方法,由static標識,一般通過類名稱調用;在少數人編碼不規範的情況下通過對象實例調用,編譯器給出警告,但予以通過;
  • 實例成員:包括實例變量和實例方法,無static標識,只能由對象實例調用;
  • 聲明類型:如A a = new AImpl(),A爲聲明類型;
  • 構造類型:如A a = new AImpl(),AImpl爲構造類型。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章