中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

動態字節碼技術 javassist 初探

發布時間:2020-08-06 03:15:09 來源:網絡 閱讀:748 作者:灰白世界 欄目:編程語言

字節碼應用場景
AOP 技術、Lombok 去除重復代碼插件、動態修改 class 文件等
字節碼技術優勢
Java 字節碼增強指的是在 Java 字節碼生成之后,對其進行修改,增強其功能,這種方式相當于對應用程序的二進制文件進行修改,Java 字節碼增強主要是為了減少冗余代碼,提高性能等 實現字節碼增強的主要步驟為:
修改字節碼,在內存中獲取到原來的字節碼,然后通過一些工具(如 ASM,Javaasist)來修改它的byte[]數組,得到一個新的byte數組
使修改后的字節碼生效

自定義 ClassLoader 來加載修改后的字節碼
替換掉原來的字節碼,在 JVM 加載用戶的 Class 時,攔截,返回修改后的字節碼,或者在運行時,使用Instrumentation.redefineClasses 方法來替換掉原來的字節碼
常見的字節碼操作類庫
BCEL
Byte Code Engineering Library(BCEL),這是Apache Software Foundation的 Jakarta 項目的一部分,BCEL 是 Java classworking 廣泛使用的一種框架,它可以讓您深入jvm匯編語言進行類庫操作的細節,BCEL 與 javassist 有不同的處理字節碼方法,BCEL 在實際的 JVM 指令層次上進行操作(BCEL 擁有豐富的 JVM 指令集支持)而 javassist 所強調的是源代碼級別的工作
ASM
是一個輕量級 Java 字節碼操作框架,直接涉及到JVM底層的操作和指令,高性能,高質量
CGLB
生成類庫,基于ASM實現
javassist
是一個開源的分析、編輯和創建 Java 字節碼的類庫,性能較 ASM 差,跟 CGLIB 差不多,但是使用簡單,很多開源框架都在使用它
Javassist 中最為重要的是 ClassPool、CtClass 、CtMethod、CtField
ClassPool:一個基于HashMap實現的 CtClass 對象容器,其中鍵是類名稱,值是表示該類的 CtClass 對象,默認的ClassPool 使用與底層 JVM 相同的類路徑,因此在某些情況下,可能需要向 ClassPool 添加類路徑或類字節
CtClass:表示一個類,這些 CtClass 對象可以從 ClassPool 獲得
CtMethods:表示類中的方法
CtFields :表示類中的字段
優勢:
比反射開銷小、性能高
操作字節碼可以動態生成新的類,動態修改類(添加、刪除、修改屬性或方法)
javassist 外層 API 和反射類似
主要有 CtClass、CtMethod、CtField 組成,執行反射中的 java.lang.Class、java.lang.reflect.Method、 java.lang.reflect.Method .Field 中的操作
劣勢:
不支持 JDK5 的新語法,包括泛型、枚舉,不支持注解修改
不支持數組初始化
不支持內部類和匿名類
不支持 continue 和 break
動態創建類
public static void main(String[] args) throws CannotCompileException, NotFoundException, IOException {
ClassPool pool = ClassPool.getDefault();
// 創建User
CtClass userClass = pool.makeClass("com.kernel.entity.User");
// 創建屬性
CtField nameField = CtField.make("private String name;", userClass);
CtField ageField = CtField.make("private Integer age;", userClass);
// 添加屬性
userClass.addField(nameField);
userClass.addField(ageField);
// 創建方法
CtMethod getName = CtMethod.make("public String getName() {return name;}", userClass);
CtMethod setName = CtMethod.make("public void setName(String name) {this.name = name;}", userClass);
// 添加方法
userClass.addMethod(getName);
userClass.addMethod(setName);
// 創建構造器
CtConstructor constructor = new CtConstructor(new CtClass[]{pool.get("java.lang.String"), pool.get("java.lang.Integer")}, userClass);
// 設置內容
constructor.setBody("{this.name = name;this.age = age;}");
// 添加構造器
userClass.addConstructor(constructor);
userClass.writeFile("D:\Codes\Java\Performance\jvm-day03\src\main\java\com\kernel\test");
}
動態添加并執行方法
public static void main(String[] args) {
try {
ClassPool pool = ClassPool.getDefault();
// 讀取com.kernel.User
CtClass userClass = pool.get("com.kernel.User");
// 創建方法,設置方法返回值
CtMethod method = new CtMethod(CtClass.voidType, "sum", new CtClass[] { CtClass.intType, CtClass.intType },
userClass);
// 設置方法內容
method.setBody("{System.out.println(\"sun:\" + ($1 + $2));}");
// 添加方法
userClass.addMethod(method);
userClass.writeFile("D:\Codes\Java\Performance\jvm-day03\src\main\java\com\kernel\test");
// 動態執行方法
Class clazz = userClass.toClass();
Object newInstance = clazz.newInstance();
// 獲得方法
Method sumMethod = clazz.getDeclaredMethod("sum", int.class, int.class);
sumMethod.invoke(newInstance, 2, 5);
} catch (Exception e) {
e.printStackTrace();
}
}

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

大石桥市| 庆安县| 阿拉善盟| 阿拉善左旗| 襄汾县| 灵寿县| 清原| 重庆市| 夹江县| 九台市| 原平市| 晴隆县| 满洲里市| 三穗县| 成都市| 洪洞县| 沁阳市| 宜阳县| 宁陵县| 呈贡县| 雷山县| 祥云县| 台江县| 罗源县| 多伦县| 融水| 留坝县| 和硕县| 孝昌县| 嘉兴市| 景宁| 常德市| 化德县| 民县| 巩留县| 罗江县| 庆城县| 射阳县| 确山县| 镇坪县| 冀州市|