Javassist是可以动态编辑Java字节码的类库。它可以在Java程序运行时定义一个新的类,并加载到JVM中;还可以在JVM加载时修改一个类文件。Javassist使用户不必关心字节码相关的规范也是可以编辑类文件的。

Javassist API
| 类 | 描述 |
|---|---|
| ClassPool | ClassPool是一个存储CtClass的容器,如果调用get方法会搜索并创建一个表示该类的CtClass对象 |
| CtClass | CtClass表示的是从ClassPool获取的类对象,可对该类就行读写编辑等操作 |
| CtMethod | 可读写的类方法对象 |
| CtConstructor | 可读写的类构造方法对象 |
| CtField | 可读写的类成员变量对象 |
代码示例
package com.ctf.ssist;import org.apache.ibatis.javassist.*;import java.util.Arrays;public class JavaSsistTest {public static void main(String[] args) throws Exception {//创建ClassPool对象ClassPool classPool = ClassPool.getDefault();try{CtClass ctClass = classPool.get("com.ctf.ssist.Test");System.out.println("解析类名:"+ ctClass.getName()+"父类"+ ctClass.getSuperclass().getName()+", 实现接口"+ Arrays.toString(ctClass.getInterfaces()));System.out.println("================================================================");//获取所有的构造方法CtConstructor[] ctConstructor = ctClass.getDeclaredConstructors();for (CtConstructor constructor : ctConstructor) {System.out.println(constructor);}System.out.println("====================================");//获取所有的成员变量CtField[] ctFields = ctClass.getDeclaredFields();for (CtField ctField : ctFields) {System.out.println(ctField);}System.out.println("====================================");//获取所有的成员方法CtMethod[] ctMethods = ctClass.getDeclaredMethods();for (CtMethod ctMethod : ctMethods) {System.out.println(ctMethod);}System.out.println("====================================");} catch (NotFoundException e){e.printStackTrace();}}}
运行结果

个人感觉这个类似于Java的反射
使用:动态创建Java类的二进制文件
package com.ctf.ssist;import org.apache.commons.io.FileUtils;import org.apache.ibatis.javassist.ClassPool;import org.apache.ibatis.javassist.CtClass;import org.apache.ibatis.javassist.CtField;import org.apache.ibatis.javassist.CtMethod;import java.io.File;public class JavassistTestPro {public static void main(String[] args) {ClassPool classPool = ClassPool.getDefault();//使用ClassPool创建一个类CtClass ctClass = classPool.makeClass("com.ctf.ssist.JavassistHelloWorld");try{CtField ctField = CtField.make("private static String content = \"yiyandingzhen\";", ctClass);ctClass.addField(ctField);CtMethod ctMethod = CtMethod.make("public static void main(String[] args) {System.out.println(content);}", ctClass);ctClass.addMethod(ctMethod);File classFilePath = new File(new File(System.getProperty("user.dir"), "/src/main/java/com/ctf/ssist/"), "JavassistHelloWorld.class");byte[] bytes = ctClass.toBytecode();FileUtils.writeByteArrayToFile(classFilePath, bytes);}catch (Exception e){e.printStackTrace();}}}
结果

