只知道java有反射可以说是动态语言,动态链接,早期晚期绑定、虚方法这些概念你知道吗
目錄
開局一張圖
動態鏈接(或指向運行時常量池的方法引用)
為什么需要常量池呢?
早期綁定晚期綁定
靜態鏈接
動態鏈接
虛方法與非虛方法
非虛方法
虛擬機中提供了以下幾條方法調用指令
關于invokedynamic指令
動態類型語言和靜態類型語言
開局一張圖
動態鏈接(或指向運行時常量池的方法引用)
? ? 每一個棧幀內部都包含一個指向運行時常量池中該棧幀所屬方法的引用。包含這個引用的目的就是為了支持當前的方法的代碼能夠實現動態鏈接(Dynamic Linking)。比如:invokedynamic指令。
? ? 在Java源文件被編譯到字節碼文件中時,所有的變量和方法引用都作為符號引用(Symbolic Reference)保存在class文件的常量池里(#xx,如下圖)。比如:描述一個方法調用了另外的其他方法時,就是通過常量池中指向方法的符號引用來表示的,那么動態鏈接的作用就是為了將這些符號引用轉換為調用方法的直接引用。
為什么需要常量池呢?
? ? 常量池的作用,就是為了提供一些符號和常量, 便于指令的識別。
早期綁定晚期綁定
?? ?在JVM中,將符號引用轉換為調用方法的直接引用與方法的綁定機制相關。
靜態鏈接
? ? 當一個字節碼文件被裝載進JVM內部時,如果被調用的目標方法在編譯期可知,且運行期保持不變。這種情況下將調用方法的符號引用轉換為直接引用的過程稱之為靜態鏈接。
動態鏈接
? ? 如果被調用的方法在編譯期無法被確定下來,也就是說,只能在程序運行期將調用方法的符號引用轉換為直接引用,由于這種引用轉換過程具備動態性,因此也就被稱之為動態鏈接。
對應的方法的綁定機制為:早期綁定(Early Binding)和晚期綁定(Late Binding)。綁定是一個字段、方法或者類在符號引用被替換為直接引用的過程,這僅僅發生一次。
? ? 早期綁定:早期綁定就是指被調用的目標方法如果在編譯期可知,且運行期保持不變時,即可將這個方法與所屬的類型進行綁定,這樣一來,由于明確了被調用的目標方法究竟是哪一個,因此也就可以使用靜態鏈接的方式將符號引用轉換為直接引用。
? ? 晚期綁定:如果被調用的方法在編譯期無法被確定下來,只能夠在程序運行期根據實際的類型綁定相關的方法,這種綁定方式也就被稱之為晚期綁定。
(繼承、實現之后,調用父類方法、接口方法(多態),是晚期綁定)
? ? 隨著高級語言的橫空出世,類似于Java一樣的基于面向對象的編程語言如今越來越多,盡管這類編程語言在語法風格上存在一定的差別,但是它們彼此之間始終保持著一個共性,那就是都支持封裝、繼承和多態等面向對象特性,既然這一類的編程語言具備多態性,那么也就具備早期綁定和晚期綁定兩種綁定方式。
? ? Java中任何一個普通的方法其實都具備虛函數的特征(具備晚期綁定的特點),它們相當于C++語言中的虛函數(C++中則需要使用關鍵字virtual來顯式定義)。如果在Java程序中不希望某個方法擁有虛函數的特征時,則可以使用關鍵字final來標記這個方法。
虛方法與非虛方法
非虛方法
? ? 如果方法在編譯期就確定了具體的調用版本,這個版本在運行時是不可變的。這樣的方法稱為非虛方法。
? ? 靜態方法、私有方法、final方法、實例構造器、父類方法都是非虛方法。
? ? 其他方法稱為虛方法。
子類對象的多態性的使用前提:1.類的繼承關系2.方法的重寫。(多態-虛方法)
虛擬機中提供了以下幾條方法調用指令
? ? 普通調用指令:
? ? 1.invokestatic:調用靜態方法,解析階段確定唯一方法版本。
? ? 2.invokespecial:調用<init>方法、私有及父類方法,解析階段確定唯一方法版本。
? ? 3.invokevirtual:調用所有虛方法。
? ? 4.invokeinterface:調用接口方法。
? ? 動態調用指令:
? ? 5.invokedynamic:動態解析出需要調用的方法,然后執行。
前四條指令固化在虛擬機內部,方法的調用執行不可人為干預,而invokedynamic指令則支持由用戶確定方法版本。其中invokestatic指令和invokespecial指令調用的方法稱為非虛方法,其余的(final修飾的除外)稱為虛方法。
關于invokedynamic指令
? ? JVM字節碼指令集一直比較穩定,一直到Java7中才增加了一個invokedynamic指令,這是Java為了實現【動態類型語言】支持而做的一種改進。
? ? 但是在Java7中并沒有提供直接生成invokedynamic指令的方法,需要借助ASM這種底層字節碼工具來產生invokedynamic指令。直到java8的Lambda表達式的出現,invokedynamic指令的生成,在java中才有了直接的生成方式。
? ? java7中增加的動態語言類型支持的本質是對java虛擬機規范的修改,而不是對java語言規則的修改,這一塊相對來講比較復雜,增加了虛擬機中的方法調用,最直接的受益者就是運行在java平臺的動態語言的編譯器。
動態類型語言和靜態類型語言
? ? 動態類型語言和靜態類型語言兩者的區別就在于對類型的檢查是否在編譯期還是在運行期,滿足前者就是靜態類型語言,反之是動態類型語言。
? ? 說的再直白一點就是,靜態類型語言是判斷變量自身的類型信息;動態類型語言是判斷變量值的類型信息,變量沒有類型信息,變量值才有類型信息,這是動態語言的一個重要特征。
js:var?name='jack';動態語言
python: info = 130;動態語言
總結
以上是生活随笔為你收集整理的只知道java有反射可以说是动态语言,动态链接,早期晚期绑定、虚方法这些概念你知道吗的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你只知道JVM栈,知不知道栈帧、局部变量
- 下一篇: 什么是java本地方法?什么,还没听说过