java操作字节码_Java知识点总结(动态字节码操作-Javassist介绍)

本文介绍了Java字节码操作的重要性和常见库,如BCEL、ASM和CGLIB。重点讲解了Javassist,一个开源的Java字节码操作类库,用于动态生成和修改类。通过示例展示了如何使用Javassist创建类、添加属性和方法,并指出其在性能、语法支持和局限性方面的特点。Javassist在AOP和反射场景中有广泛应用。
摘要由CSDN通过智能技术生成

Java知识点总结(动态字节码操作-Javassist介绍)

@(Java知识点总结)[Java, 动态字节码操作]

运行时操作字节码可以让我们实现如下功能:

动态生成新的类

动态改变某个类的结构(添加/删除/修改 新的属性/方法)

java常见的字节码操作类库

BCEL

Byte Code Engineering Library (BCEL) ,这是 Apache Software Foundation 的 Jakarta 项目的一部分。 BCEL 是 Java classworking 广泛 使用的一种 框架 , 它 可以让您深入 JVM 汇编语言进行类操作的细节。 BCEL 与 Javassist 有不同的处理字节码方法, BCEL 在实际的 JVM 指令层次上进行操作 (BCEL 拥有丰富的 JVM 指令级支持 ) 而 Javassist 所 强调 的是源代码 级别的 工作 。

ASM

是一个轻量级 java 字节码操作框架,直接涉及到 JVM 底层的操作和 指令

CGLIB(Code Generation Library)

是一个强大的,高性能,高质量的 Code

Javassist

是 一个开源的分析、编辑和创建 Java 字节码 的类库 。性能较 ASM 差,跟 cglib 差不多,但是使用简单。很多开源框架都在使用它 。

主页:http://www.csg.ci.i.u-tokyo.ac.jp/~ chiba/javassist

Javassist

使用Javassist需要使用javassist.jar

优势:

比反射开销小,性能高。

JAVAsist性能高于反射,低于ASM

局限性:

JDK新语法不支持(包括泛型、枚举),不支持注解修改,但可以通过底层的javasist类来解决,具体参考:javassist.bytecode.annotaion

不支持数组的初始化,如 String[]{"1","2"},除非只有数组的容量为1

不支持内部类和匿名类

不支持 continue 和 break 表达式。

对于继承关系,有些不支持 。例如:- class A{} - class B extends A{} - class C enxends B {}

应用场景:

AOP:

给一个类增加新的方法

给一段语句前面和后面(before/after/around)动态的加代码

Reflection:起到类似反射的效果

javassist 的最外层的 API 和 JAVA 的反射包中的 API 颇为类似 。

它主要由 CtClass , CtMethod, ,以及 CtField 几个类组成。用以执行和 JDK 反射 API 中 java.lang.Class , java.lang.reflect.Method , java.lang.reflect.Method .Field 相同的 操作 。

方法操作

修改已有方法的方法体体(插入代码到已有方法体)

新增方法 删除方法

占位符参数介绍:

799e71fc55b0292a634bc65e89070891.png

示例:

import javassist.ClassPool;

import javassist.CtClass;

import javassist.CtConstructor;

import javassist.CtField;

import javassist.CtMethod;

/**

* 创建一个新的类

* @author Administrator

*

*/

public class Test10 {

public static void main(String[] args) throws Exception {

ClassPool pool = ClassPool.getDefault(); // 类池

CtClass class1 = pool.makeClass("com.gs.Emp");

//创建属性

CtField f1 = CtField.make("private int num;", class1);

CtField f2 = CtField.make("private String name;", class1);

class1.addField(f1);

class1.addField(f2);

//创建方法

CtMethod setName = CtMethod.make("public void setName(String name){this.name = name;}", class1);

CtMethod getName = CtMethod.make("public String getName(){return name;}", class1);

class1.addMethod(setName);

class1.addMethod(getName);

//添加构造器。 如果是带参构造器,需要传递参数类型,基本数据类型用CtClass获取,引用类型,需要用pool获取

CtConstructor constructor = new CtConstructor(new CtClass[]{CtClass.intType,pool.get("java.lang.String")}, class1);

constructor.setBody("{this.num = num;this.name = name;}"); //构造器的方法体

class1.writeFile("E:/myjava"); //将上面写好的类,写入到这个工作空间中

System.out.println("生成类成功!");

}

}

执行结果:

生成类成功!

6bb2b47702fad4f985a7dcfbeaf222c5.png

使用反编译工具xjad打开:

316f4237d8101d77f26a8241791e128a.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值