国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

動(dòng)態(tài)類型的語言支持--invokedynamic

2019-11-14 11:57:38
字體:
供稿:網(wǎng)友

invokedynamic是為了實(shí)現(xiàn)lambda表達(dá)式做的技術(shù)準(zhǔn)備。

動(dòng)態(tài)類型語言

動(dòng)態(tài)類型語言的關(guān)鍵特征是它的類型檢查的主體過程是在運(yùn)行期而不是編譯期進(jìn)行的,例如:APL、Clojure、Erlang、Groovy、javaScript、Jython、Lisp、Lua、phpPRolog、Python、Ruby、Smalltalk和Tcl等等。那相對(duì)地,在編譯期就進(jìn)行類型檢查過程的語言,如C++和Java等就是最常用的靜態(tài)類型語言。

這種差別產(chǎn)生的原因是靜態(tài)類型語言在編譯期間已將方法完整的符號(hào)引用生成出來,作為方法調(diào)用指令的參數(shù)存儲(chǔ)到Class文件中。 這個(gè)符號(hào)引用包含了此方法定義在哪個(gè)具體類型之中、方法的名字以及參數(shù)順序、參數(shù)類型和方法返回值等信息,通過這個(gè)符號(hào)引用,虛擬機(jī)就可以翻譯出這個(gè)方法的直接引用(譬如方法內(nèi)存地址或者其他實(shí)現(xiàn)形式)。而在動(dòng)態(tài)類型語言中,變量本身是沒有類型的,變量的值才具有的類型,編譯時(shí)候最多只能確定方法名稱、參數(shù)、返回值這些信息,而不會(huì)去確定方法所在的具體類型(方法接收者不固定)。“變量無類型而變量值才有類型”這個(gè)特點(diǎn)也是動(dòng)態(tài)類型語言的一個(gè)重要特征。

靜態(tài)類型語言在編譯期確定類型,最顯著的好處是編譯器可以提供嚴(yán)謹(jǐn)?shù)念愋蜋z查,這樣與類型相關(guān)的問題能在編碼的時(shí)候就及時(shí)發(fā)現(xiàn),利于穩(wěn)定性及代碼達(dá)到更大的規(guī)模。而動(dòng)態(tài)類型語言在運(yùn)行期確定類型,這可以為開發(fā)人員提供更大的靈活性,某些在靜態(tài)類型語言中要花大量臃腫代碼來實(shí)現(xiàn)的功能,由動(dòng)態(tài)類型語言來實(shí)現(xiàn)可能會(huì)很清晰簡潔,清晰簡潔通常也就意味著開發(fā)效率的提升。

JDK 7與動(dòng)態(tài)類型

Java虛擬機(jī)層面對(duì)動(dòng)態(tài)類型語言的支持一直都有所欠缺,主要表現(xiàn)在方法調(diào)用方面:JDK 7以前字節(jié)碼指令集中,四條方法調(diào)用指令(invokevirtual、invokespecial、invokestatic、invokeinterface)的第一個(gè)參數(shù)都是被調(diào)用的方法的符號(hào)引用(CONSTANT_Methodref_info或者CONSTANT_InterfaceMethodref_info常量),前面已經(jīng)提到過,方法的符號(hào)引用在編譯時(shí)產(chǎn)生,而動(dòng)態(tài)類型語言只有在運(yùn)行期才能確定接收者類型。這樣,在Java虛擬機(jī)上實(shí)現(xiàn)的動(dòng)態(tài)類型語言就不得不使用“曲線救國”的方式(如編譯時(shí)留個(gè)占位符類型,運(yùn)行時(shí)動(dòng)態(tài)生成字節(jié)碼實(shí)現(xiàn)具體類型到占位符類型的適配)來實(shí)現(xiàn),這樣勢(shì)必讓動(dòng)態(tài)類型語言實(shí)現(xiàn)的復(fù)雜度增加,也可能帶來額外的性能或者內(nèi)存開銷。盡管可以想一些辦法(如Call Site Caching)讓這些開銷盡量變小,但這種底層問題終歸是應(yīng)當(dāng)在虛擬機(jī)層次上去解決才最合適,因此在Java虛擬機(jī)層面上提供動(dòng)態(tài)類型的直接支持就成為了Java平臺(tái)的發(fā)展趨勢(shì)之一,這就是JDK 7(JSR-292)中invokedynamic指令以及java.lang.invoke包出現(xiàn)的技術(shù)背景。

java.lang.invoke包

java.lang.invoke包的主要目的是在之前單純依靠符號(hào)引用來確定調(diào)用的目標(biāo)方法這條路之外提供一種新的動(dòng)態(tài)確定目標(biāo)方法的機(jī)制,稱為Method Handle。

MethodHandle與Reflection區(qū)別:

Reflection和MethodHandle機(jī)制本質(zhì)上都是在模擬方法調(diào)用,但是Reflection是在模擬Java代碼層次的方法調(diào)用,而MethodHandle是在模擬字節(jié)碼層次的方法調(diào)用。在MethodHandles.Lookup上的三個(gè)方法findStatic()、findVirtual()、findSpecial()正是為了對(duì)應(yīng)于invokestatic、invokevirtual&invokeinterface和invokespecial這幾條字節(jié)碼指令的執(zhí)行權(quán)限校驗(yàn)行為,而這些底層細(xì)節(jié)在使用Reflection API時(shí)是不需要關(guān)心的。Reflection中的java.lang.reflect.Method對(duì)象遠(yuǎn)比MethodHandle機(jī)制中的java.lang.invoke.MethodHandle對(duì)象所包含的信息來得多。前者是方法在Java一端的全面映像,包含了方法的簽名、描述符以及方法屬性表中各種屬性的Java端表示方式,還包含有執(zhí)行權(quán)限等的運(yùn)行期信息。而后者僅僅包含著與執(zhí)行該方法相關(guān)的信息。用開發(fā)人員通俗的話來講,Reflection是重量級(jí),而MethodHandle是輕量級(jí)。

由于MethodHandle是對(duì)字節(jié)碼的方法指令調(diào)用的模擬,那理論上虛擬機(jī)在這方面做的各種優(yōu)化(如方法內(nèi)聯(lián)),在MethodHandle上也應(yīng)當(dāng)可以采用類似思路去支持(但目前實(shí)現(xiàn)還不完善)。而通過反射去調(diào)用方法則不行。

  MethodHandle與Reflection除了上面列舉的區(qū)別外,最關(guān)鍵的一點(diǎn)還在于去掉前面討論施加的前提“僅站在Java語言的角度看”之后:Reflection API的設(shè)計(jì)目標(biāo)是只為Java語言服務(wù)的,而MethodHandle則設(shè)計(jì)為可服務(wù)于所有Java虛擬機(jī)之上的語言,其中也包括了Java語言而已。

使用詳解:通過代碼簡單介紹JDK 7的MethodHandle,并與.NET的委托對(duì)比 純轉(zhuǎn)一篇關(guān)于方法句柄的,對(duì)理解很多java poc幫助很大

invokedynamic指令

每一處含有invokedynamic指令的位置都被稱作“動(dòng)態(tài)調(diào)用點(diǎn)(Dynamic Call Site)”,這條指令的第一個(gè)參數(shù)不再是代表方法符號(hào)引用的CONSTANT_Methodref_info常量,而是變?yōu)镴DK 7新加入的CONSTANT_InvokeDynamic_info常量,從這個(gè)新常量中可以得到3項(xiàng)信息:引導(dǎo)方法(Bootstrap Method,此方法存放在新增的BootstrapMethods屬性中)、方法類型(MethodType)和名稱。引導(dǎo)方法是有固定的參數(shù),并且返回值是java.lang.invoke.CallSite對(duì)象,這個(gè)代表真正要執(zhí)行的目標(biāo)方法調(diào)用。根據(jù)CONSTANT_InvokeDynamic_info常量中提供的信息,虛擬機(jī)可以找到并且執(zhí)行引導(dǎo)方法,從而獲得一個(gè)CallSite對(duì)象,最終調(diào)用要執(zhí)行的目標(biāo)方法上。我們還是照例拿一個(gè)實(shí)際例子來解釋這個(gè)過程吧。如下面代碼清單所示:


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 祁门县| 竹溪县| 岳西县| 澄迈县| 忻城县| 常州市| 呈贡县| 泾川县| 北安市| 玉山县| 丁青县| 大港区| 威海市| 永新县| 盐池县| 加查县| 崇仁县| 河北区| 宁德市| 股票| 安乡县| 无极县| 华容县| 长阳| 江源县| 龙岩市| 杭锦后旗| 闽清县| 天峨县| 乐昌市| 临邑县| 德化县| 阿城市| 康乐县| 钟山县| 雅江县| 留坝县| 南涧| 营口市| 新民市| 邳州市|