第24講丨有哪些方法可以在運(yùn)行時動態(tài)生成一個java類_第1頁
第24講丨有哪些方法可以在運(yùn)行時動態(tài)生成一個java類_第2頁
第24講丨有哪些方法可以在運(yùn)行時動態(tài)生成一個java類_第3頁
第24講丨有哪些方法可以在運(yùn)行時動態(tài)生成一個java類_第4頁
第24講丨有哪些方法可以在運(yùn)行時動態(tài)生成一個java類_第5頁
已閱讀5頁,還剩12頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

JavaProcessBuilderjavaclow你可以考慮使用JavaCompilerAPI,這是JDK提供的標(biāo)準(zhǔn)API,里面提供了與javac對 進(jìn)一步思考,圍繞Java源碼編譯成為JVM可以理解的字節(jié)碼,換句話說,只要是符合JVM規(guī)范的字節(jié)碼,不管它是如何生成的,是不是都可以被JVM加載呢?我們能當(dāng)然也可以,不過直接去寫字節(jié)碼難度太大,通常我們可以利用Java字節(jié)碼工具和類庫來實(shí)現(xiàn),比如在專欄第6講中提到的ASM、Javassist、cglib等。雖然曾經(jīng)被視為黑魔法,但在當(dāng)前復(fù)雜多變的開發(fā)環(huán)境中,在運(yùn)行時動態(tài)生成邏輯并不是什么罕見的場景。重新審視我們談到的動態(tài),本質(zhì)上不就是在特定的時機(jī),去修改已有類型實(shí)現(xiàn),或者創(chuàng)建新的類型。如何利用字節(jié)碼技術(shù),實(shí)現(xiàn)基本的動態(tài)邏輯?Class過下面的方法提供的功能,或者defineClass的其他本地對等實(shí)現(xiàn)。protectedfinalClass<?>defineClass(Stringname,byte[]b,intoff,intProtectionprotectionprotectedfinalClass<?>defineClass(Stringname,java.nio.ByteBufferProtectionprotection我這里只選取了最基礎(chǔ)的兩個典型的defineClass實(shí)現(xiàn),Java重載了幾個不同的方法。可以看出,只要能夠生成出規(guī)范的字節(jié)碼,不管是作為byte數(shù)組的形式,還是放到JDK提供的defineClassstaticnativeClass<?>defineClass1(ClassLoaderloader,Stringname,byte[]b,intProtectionpd,String3staticnativeClass<?>defineClass2(ClassLoaderloader,Stringname,intoff,intlen,ProtectionString更進(jìn)一步,我們來看看JDKdynamic Builder這個靜態(tài)內(nèi)部類中,Generator生成字節(jié)碼,并以byte數(shù)組的形式保存,然后通過調(diào)用Unsafe提供的defineClass。byte[]ClassFile=Generator.generate Name,interfaces.toArray(EMPTY_CLASS_ARRAY),tryClass<?>pc=UNSAFE.defineClass(Name,0,loader,reverseCache.sub(pc).putIfAbsent(loader,return}catch(ClassFormatErrore)//如果出現(xiàn)ClassFormatError,很可能是輸入?yún)?shù)有問題,比如,Generator有}前面理順了二進(jìn)制的字節(jié)碼信息到Class對象的轉(zhuǎn)換過程,似乎我們還沒有分析如何生成JDK內(nèi)部動態(tài)的邏輯,可以參考java.lang.reflect.Generator的內(nèi)部實(shí)現(xiàn)。我覺得可以認(rèn)為這是種另類的字節(jié)碼技術(shù),其利用了DataOutputStrem提供的能力,配合hard-coded的各種JVM指令實(shí)現(xiàn)方法,生成所需的字節(jié)碼數(shù)組。你可以參考下面的示例privatevoidcodeLocalLoadStore(intlvar,intopcode,intDataOutputStreamthrows4assertlvar>=0&&lvar<=//根據(jù)變量數(shù)值,以不同格式,dump7(lvar<=3)8out.writeByte(opcode_0+9}elseif(lvar<=0xFF)out.writeByte(lvar&}else//使用寬指令修飾符,如果變量索引不能用無符號out.writeShort(lvar&18}這種實(shí)現(xiàn)方式的好處是沒有太多依賴關(guān)系,簡單實(shí)用,但是前提是你需要懂各種JVM指令,知道怎么處理那些偏移地址等,實(shí)際門檻非常高,所以并不適合大多數(shù)的普通開發(fā)場景。幸好,Java么都自己從頭做。JDK內(nèi)部就集成了ASM類庫,雖然并未作為公共API出來,但是它廣泛應(yīng)用在,如java.lang.instrumentationAPI底層實(shí)現(xiàn),或者LambdaCallSite生成的內(nèi)部邏輯中,這些代碼的實(shí)現(xiàn)我就不在這里展開了,如果你確實(shí)有或有需要,可以參考類似LamdaForm的字節(jié)碼生成邏輯:java.lang.invoke.InvokerBytecodeGenerator對于一個普通的Java動態(tài),其實(shí)現(xiàn)過程可以簡化成為 ,如com.mycorp. 實(shí)現(xiàn)InvocationHandler,對對象方法的調(diào)用,會被分派到其invoke方法來真正實(shí)通過類,調(diào)用其newInstance方法,生成一個實(shí)現(xiàn)了相應(yīng)基礎(chǔ)接口的1publicstaticObjectnewInstance(ClassLoader Class<?>[] InvocationHandlerASMASMJavaASM1ClassWritercw=new 23 //指定Java4//說明是public5//6//簽名,null //newString[]{" o"});//MethodVisitormv= //公共方 //方法名 // //簽名,null //7// //visitX類型,創(chuàng)建各種方法等邏輯。ASMAPI,廣泛的使用了Visitor模式,如果你熟悉這個模byte,ClassWriterASMMockORMIOCProfiler今天我們探討了更加深入的類加載和字節(jié)碼操作方面技術(shù)。為了理解底層的原理,我選取的例子是比較偏底層的、能力全面的類庫,如果實(shí)際項(xiàng)目中需要進(jìn)行基礎(chǔ)的字節(jié)碼操作,可以考慮使用更加次視角的類庫,例如ByeBudy等。關(guān)于今天我們討論的題目你做到心中有數(shù)了嗎?試想,假如我們有這樣一個需求,需要添加某個功能,例如對某類型資源如網(wǎng)絡(luò)通信的消耗進(jìn)行統(tǒng)計(jì),重點(diǎn)要求是,不開啟時必須是零開銷,而不是低開銷,可以利用我們今天談到的或者相關(guān)的技術(shù)實(shí)現(xiàn)嗎?請你在留言區(qū)寫寫你對這個問題的思考,我會選出經(jīng)過認(rèn)真思考的留言,送給你一份學(xué)習(xí)獎你的朋友是不是也在準(zhǔn)備面試呢?你可以“請朋友讀”,把今天的題目給好友,或許你 不得售賣。頁面已增加防盜追蹤,將依法其上一 第23講|請介紹類加載過程,什么是雙親委派模型下一 第25講|談?wù)凧VM內(nèi)存區(qū)域的劃分,哪些區(qū)域可能發(fā)生三口先 27 四阿 3 無痕埋點(diǎn)原理就是

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論