棧幀中動態連接的理解


“棧幀內部包含一個指向運行時常量池中該棧幀所屬方法的引用,該引用的目的支持動態代理”

 

1.方法區中字節碼已經有直接引用為什么還要在棧幀里放?

Child類繼承Father類,並重寫doSomething方法:

 

 

 

在靜態解析時候,看到變量father和child的靜態類型都是Father,所以,doSomething方法都解析成Father類里的方法。而child變量的實際類型是Child,應該調用Child類里的doSomething方法,因此方法區里靜態解析式不完全正確,要在運行期間棧幀進棧的時候動態連接到真實的類和方法。

 

2. 已經創建了棧幀,還存一個指向自己的地址多余嗎?

動態連接發生在棧幀完全入棧之前,也在局部變量表等形成之前。

以Test類最后一條語句child.doSomething為例。執行到該條語句之時,找到doSomething的直接引用,即在方法區里的地址。形成了指向Child類doSomething方法的動態連接,找到了該方法的入口,也就找到了對應得字節碼指令,有了局部變量表和操作數棧的出入棧,然后形成了doSomething這個方法的棧幀。字節碼指令指行完后,doSomething方法的棧幀出棧,根據返回地址,返回到test方法繼續執行。

 

動態連接是找到正確方法的入口,然后才有后來的進棧出棧的執行。

 

3. 靜態多分派

由1中的例子可知,編譯期是根據對象聲明的類型來選擇方法。調用過程中首先確定調用者的靜態類型是什么,即child的靜態類型Father,然后根據要調用的方法參數的靜態類型(聲明類型)確定所有重載方法中要調用哪一個(方法重載)。兩者共同決定所以是多分派。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM