Java方法的静态绑定与动态绑定讲解
?一:綁定
??????? 把一個方法與其所在的類/對象 關(guān)聯(lián)起來叫做方法的綁定。綁定分為靜態(tài)綁定(前期綁定)和動態(tài)綁定(后期綁定)。
???
??? 二:靜態(tài)綁定
??????? 靜態(tài)綁定(前期綁定)是指:在程序運行前就已經(jīng)知道方法是屬于那個類的,在編譯的時候就可以連接到類的中,定位到這個方法。
??????? 在Java中,final、private、static修飾的方法以及構(gòu)造函數(shù)都是靜態(tài)綁定的,不需程序運行,不需具體的實例對象就可以知道這個方法的具體內(nèi)容。
?
??? 三:動態(tài)綁定
??????? 動態(tài)綁定(后期綁定)是指:在程序運行過程中,根據(jù)具體的實例對象才能具體確定是哪個方法。
??????? 動態(tài)綁定是多態(tài)性得以實現(xiàn)的重要因素,它通過方法表來實現(xiàn):每個類被加載到虛擬機時,在方法區(qū)保存元數(shù)據(jù),其中,包括一個叫做 方法表(method table)的東西,表中記錄了這個類定義的方法的指針,每個表項指向一個具體的方法代碼。如果這個類重寫了父類中的某個方法,則對應(yīng)表項指向新的代碼實現(xiàn)處。從父類繼承來的方法位于子類定義的方法的前面。
????????動態(tài)綁定語句的編譯、運行原理:我們假設(shè) Father ft=new Son();? ft.say();? Son繼承自Father,重寫了say()。
??????? 1:編譯:我們知道,向上轉(zhuǎn)型時,用父類引用執(zhí)行子類對象,并可以用父類引用調(diào)用子類中重寫了的同名方法。但是不能調(diào)用子類中新增的方法,為什么呢?
???????????????????? 因為在代碼的編譯階段,編譯器通過?聲明對象的類型(即引用本身的類型)?在方法區(qū)中該類型的方法表中查找匹配的方法(最佳匹配法:參數(shù)類型最接近的被調(diào)用),如果有則編譯通過。(這里是根據(jù)聲明的對象類型來查找的,所以此處是查找 Father類的方法表,而Father類方法表中是沒有子類新增的方法的,所以不能調(diào)用。)
???????????????????? 編譯階段是確保方法的存在性,保證程序能順利、安全運行。
??????? 2:運行:我們又知道,ft.say()調(diào)用的是Son中的say(),這不就與上面說的,查找Father類的方法表的匹配方法矛盾了嗎?不,這里就是動態(tài)綁定機制的真正體現(xiàn)。
???????????????????? 上面編譯階段在 聲明對象類型 的方法表中查找方法,只是為了安全地通過編譯(也為了檢驗方法是否是存在的)。而在實際運行這條語句時,在執(zhí)行 Father ft=new Son(); 這一句時創(chuàng)建了一個Son實例對象,然后在 ft.say() 調(diào)用方法時,JVM會把剛才的son對象壓入操作數(shù)棧,用它來進行調(diào)用。而用實例對象進行方法調(diào)用的過程就是動態(tài)綁定:根據(jù)實例對象所屬的類型去查找它的方法表,找到匹配的方法進行調(diào)用。我們知道,子類中如果重寫了父類的方法,則方法表中同名表項會指向子類的方法代碼;若無重寫,則按照父類中的方法表順序保存在子類方法表中。故此:動態(tài)綁定根據(jù)對象的類型的方法表查找方法是一定會匹配(因為編譯時在父類方法表中以及查找并匹配成功了,說明方法是存在的。這也解釋了為何向上轉(zhuǎn)型時父類引用不能調(diào)用子類新增的方法:在父類方法表中必須先對這個方法的存在性進行檢驗,如果在運行時才檢驗就容易出危險——可能子類中也沒有這個方法)。
?
??? 四:區(qū)分
??????? 程序在JVM運行過程中,會把類的類型信息、static屬性和方法、final常量等元數(shù)據(jù)加載到方法區(qū),這些在類被加載時就已經(jīng)知道,不需對象的創(chuàng)建就能訪問的,就是靜態(tài)綁定的內(nèi)容;需要等對象創(chuàng)建出來,使用時根據(jù)堆中的實例對象的類型才進行取用的就是動態(tài)綁定的內(nèi)容。
?
參考https://www.cnblogs.com/ygj0930/p/6554103.html
轉(zhuǎn)載于:https://www.cnblogs.com/zyx1205/p/8624684.html
總結(jié)
以上是生活随笔為你收集整理的Java方法的静态绑定与动态绑定讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mongo学习链接
- 下一篇: 推荐:Java性能优化系列集锦