前言
Java 字节码以二进制的形式存储在 class 文件中,每一个 class 文件包含一个 Java 类或接口。
Javaassist 就是一个用来处理 Java 字节码的类库
Javassist是一个开源的分析、编辑和创建Java字节码的类库,可以直接编辑和生成Java生成的字节码。相对于bcel, asm等这些工具,开发者不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。javassist简单易用, 快速。javassist是jboss的一个子项目。
重要的类
接下来来介绍类库里几个比较重要的类
ClassPool:
javassist的类池,使用ClassPool 类可以跟踪和控制所操作的类,它的工作方式与 JVM 类装载器非常相似
CtClass
CtClass表示类,一个CtClass(编译时类)对象可以处理一个class文件
CtMethod
表示类的方法
ClassClassPath
用于获取类文件的搜索路径。
CtFields
表示类的字段
代码实例
首先构造两段代码,
public class persion {private int age;private String name;public int getAge() {return age;}public void setAge(int age) { this.age = age;}public String getName() { return name;}public void setName(String name) { this.name = name;}public void sayHello(){System.out.println("Hello, My name is " + this.name);}}
public class main {public static void main(String[]args) {persion persion =new persion();persion.setName("ice");persion.sayHello();}}
toclass
import javassist.*;public class main {public static void main(String[]args) throws NotFoundException, CannotCompileException, IllegalAccessException, InstantiationException {ClassPool pool = ClassPool.getDefault();//加载类池库,默认获取所有JVMCtClass ctClass = pool.get("persion"); //从类池库里获取persion类CtMethod ctMethod=ctClass.getDeclaredMethod("sayHello");//获取sayHello方法//插入这么一段代码ctMethod.insertAfter("System.out.println(\" this is add ===I'm \" + this.age + \" years old.\");");//再转为classClass<?> newa = ctClass.toClass();//实例化persion persion = (persion) newa.newInstance();persion.setName("ice");persion.getAge(11);persion.sayHello();}}
tobyte
import javassist.*;import java.io.IOException;import java.util.Arrays;public class main {public static void main(String[]args) throws NotFoundException, CannotCompileException, IllegalAccessException, InstantiationException, IOException {ClassPool pool = ClassPool.getDefault();//加载类池库,默认获取所有JVMCtClass ctClass = pool.get("persion"); //从类池库里获取persion类CtMethod ctMethod=ctClass.getDeclaredMethod("sayHello");//获取sayHello方法//插入这么一段代码ctMethod.insertBefore("System.out.println(\" this is add ===I'm \" + this.age + \" years old.\");");//再转为classbyte[] newa = ctClass.toBytecode();//实例化String s = Arrays.toString(newa);System.out.println(s);}}

我们在上述代码中添加了一个println,并且成功对其进行TolClass操作和ToBytes操作,这也就意味着class和bytes是可以互相转化的。
总结
javassist就是能在代码写的类之后,利用直接编辑所生成的字节码,从而产生一个“新”的类。
因此javassist也常用于动态代理功能。

