term:
靜態繫結: 在編譯期就已經知道呼叫哪個物件的什麼方法。
動態繫結: 只有到執行期才知道呼叫哪個物件的什麼方法。
假定乙個物件x(其為x類),呼叫m方法: x.m();
jvm實際的動作是怎麼樣的呢?
1. 根據物件x的型別資訊(x類),找出x類中的所有的名字為m的方法.
2. 根據x類的型別資訊,找出x類父類的所有的名稱為m的方法.
前兩步能夠找出x物件能呼叫的所有m方法。
3. 根據呼叫語句提供的引數型別,唯一確定乙個方法. 當找不到任何方法、找到乙個以上的方法與之匹配,編譯器報錯.
匹配原則:(最精確匹配,相容匹配)
3.1 過載方法的解決方案: 根據引數列表給出。
3.2 包含型別轉換的部分: 按最精確匹配原則。
基本資料型別: 如:x.m(1); 1 --> 預設的整型. 首先尋找有無int,再尋找有無long型.再尋找float,最後尋找有無double
short shortvalue = 1; x.m(shortvalue); 起點為short --> int --> long --> float --> double.
首先尋找當前類,否則尋找當前類的父類,一直往上層尋找,直至找到object類.
4. 確定當前方法是否為靜態繫結方法。如果是靜態方法直接使用編譯期的方法。
4.1 當方法被宣告為private, final, static 修飾時,該方法為靜態方法
4.1.1 private方法無法被覆蓋,那麼呼叫必然是當前類的方法。
4.1.2 final方法同樣保證無法被覆蓋。
4.1.3 static修飾表明該方法屬於某個類,自然是不會產生動態繫結的問題。
4.2 當方法為構造方法時:由於構造方法是無法被繼承的,自然也需要動態繫結
5. 當該方法為動態繫結方法時:在執行期,jvm判定真實的物件型別是什麼型別.
該真實型別必定是被宣告型別的子類(編譯器保證),那麼檢查該子類是否有對應的方法的覆蓋,如果有,呼叫子類的方法,否則呼叫父類的方法。
然而每次都去搜尋子類中是否有對應的方法是十分耗時的,所以jvm採取了類資訊儲存方法呼叫表的策略來減少動態繫結方法帶來的時間的消耗。
5.1 搜尋實際物件的類資訊儲存方法呼叫表.尋找對應方法的簽名,並直接導向需要呼叫的部分.
假設:x: 基類 e: 擴充套件類
x擁有方法: m(int),m(double)
e額外擁有方法 m(int),m(string)
那麼jvm虛擬機器分別在x類中維護乙個方法呼叫表
x
m(int) --> x.m(int)
m(double) --> x.m(double)
em(int) --> e.m(int)
m(double) --> x.m(double)
m(string) --> e.m(string)
那麼確定方法的方式,是直接查實際型別的方法呼叫表就可以了。而不需要總是去搜尋本類的資訊,再確定執行哪個方法。
這樣是比較高效的。
多型,動態繫結
呼叫方法時,只要方法重寫了,實際當中調哪個,要看實際中new哪個物件。color red 好處 可擴充套件性達到最好。color 當增加東西時,不需要改原來的結構,直接加上就可以了。color red 多型的存在必要條件 1 要有繼承,2 要有重寫,3 父類引用指向子類物件。color packag...
動態繫結和多型
動態繫結是指 在執行期間 即非編譯期 判斷所引用物件的實際型別,根據其實際的型別呼叫其相應的方法。多型的存在有三個必要條件 1,要求繼承 2,要有重寫 3,父類引用指向子類物件 例 class animal public void enjoy class cat extends animal pub...
多型 動態繫結 實驗
定義三個類,父類geometricobject代表幾何形狀,子類circle代表圓形,myrectangle代表矩形。定義乙個測試類test,編寫equalsarea方法測試兩個物件的面積是否相等 注意方法的引數型別,利用動態繫結技術 編寫displaygeometricobject方法顯示物件的面...