總結:我們大多數時候都是靜態編譯,寫好java 開發工具或者構建 就給編譯了,有沒有動態生成類,然后執行呢,答案是有的,如動態代理的具體實現。
介紹:
反射:就是通過在運行時獲得類型信息然后做相應的操作。
動態編譯:動態編譯是從Java 6開始支持的,主要是通過一個JavaCompiler接口來完成的。通過這種方式我們可以直接編譯一個已經存在的java文件,也可以在內存中動態生成Java代碼,動態編譯執行。
調用JavaScript引擎:Java 6加入了對Script(JSR223)的支持。這是一個腳本框架,提供了讓腳本語言來訪問Java內部的方法。你可以在運行的時候找到腳本引擎,然后調用這個引擎去執行腳本。這個腳本API允許你為腳本語言提供Java支持。
動態生成字節碼:這種技術通過操作Java字節碼的方式在JVM中生成新類或者對已經加載的類動態添加元素。
動態編程解決什么問題
在靜態語言中引入動態特性,主要是為了解決一些使用場景的問題。
完全使用靜態編程也辦的到,只是付出的代價比較高,沒有動態編程來的優雅。例如依賴注入框架Spring使用了反射,而Dagger2 卻使用了代碼生成的方式(APT)。
如
1、在那些依賴關系需要動態確認的場景:
2、需要在運行時動態插入代碼的場景,比如動態代理的實現。
3、通過配置文件來實現相關功能的場景
Javassist
操作java字節碼的工具BECL/ASM/CGLIB/Javassit
其中有兩個比較流行,一個是ASM,一個是Javassit。
ASM 直接操作字節碼指令,執行效率高,要是使用者掌握Java類字節碼文件格式及指令,對使用者的要求比較高。
Javassit 提供了更高級的API,執行效率相對較差,但無需掌握字節碼指令的知識,對使用者要求較低。
Javassit 是一個開源的分析、編輯和創建Java字節碼的類庫。是由東京工業大學的數學和計算機科學系的 Shigeru Chiba (千葉 滋)所創建的。它已加入了開放源代碼JBoss應用服務器項目,通過使用Javassist對字節碼操作為JBoss實現動態AOP框架。javassist是jboss的一個子項目,其主要的優點,在於簡單,而且快速。直接使用java編碼的形式,而不需要了解虛擬機指令,就能動態改變類的結構,或者動態生成類。
Javassist中最為重要的是ClassPool,CtClass ,CtMethod 以及 CtField這幾個類。
ClassPool:一個基於HashMap實現的CtClass對象容器,其中鍵是類名稱,值是表示該類的CtClass對象。默認的ClassPool使用與底層JVM相同的類路徑,因此在某些情況下,可能需要向ClassPool添加類路徑或類字節。
CtClass:表示一個類,這些CtClass對象可以從ClassPool獲得。
CtMethods:表示類中的方法。
CtFields :表示類中的字段。
這里以jJdkCompiler 為例 參考 dubbo 地址如下:
https://github.com/apache/dubbo/blob/master/dubbo-common/src/main/java/org/apache/dubbo/common/compiler/support/JdkCompiler.java
我的例子如下:
是不是覺得很6,雙擊666 吧