javassist的作用是动态生成字节码。
package com.zhang; class Fighter {} public class Assist_Test { public static void main_modify(String[] args) throws NotFoundException, CannotCompileException, IOException { //修改已有类,添加name字段。前提是该类没有被加载 ClassPool pool = ClassPool.getDefault(); //CtClass (compile-time class) CtClass cc = pool.get("com.zhang.Fighter"); cc.addField(new CtField(pool.get("java.lang.String"), "name", cc)); //生成class文件 //translates the CtClass object into a class file and writes it on a local disk cc.writeFile(); } public static void main(String[] args) throws CannotCompileException, NotFoundException, InstantiationException, IllegalAccessException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { // 创建类 ClassPool pool = ClassPool.getDefault(); CtClass cls = pool.makeClass("com.zhang.Player"); // 添加私有成员name及其getter、setter方法 CtField nameField = new CtField(pool.get("java.lang.String"), "name", cls); nameField.setModifiers(Modifier.PRIVATE); cls.addField(nameField, Initializer.constant("")); cls.addMethod(CtNewMethod.setter("setName", nameField)); cls.addMethod(CtNewMethod.getter("getName", nameField)); // 添加无参的构造体 CtConstructor cons = new CtConstructor(new CtClass[] {}, cls); cons.setBody("{name = "default";}"); cls.addConstructor(cons); // 添加有参的构造体 cons = new CtConstructor(new CtClass[] {pool.get("java.lang.String")}, cls); cons.setBody("{$0.name = $1;}"); cls.addConstructor(cons); // 打印创建类的类名 Class playerClass = cls.toClass(); System.out.println(playerClass); // 通过反射创建无参的实例,并调用getName方法 Object obj = Class.forName("com.zhang.Player").newInstance(); Method getter = obj.getClass().getMethod("getName"); System.out.println(getter.invoke(obj)); // 调用其setName方法 Method setter = obj.getClass().getMethod("setName", new Class[] {String.class}); setter.invoke(obj, "zhang"); System.out.println(getter.invoke(obj)); // 通过反射创建有参的实例,并调用getName方法 obj = Class.forName("com.zhang.Player").getConstructor(String.class).newInstance("nobody"); getter = obj.getClass().getMethod("getName"); System.out.println(getter.invoke(obj)); } }
dubbo中的JavassistCompiler和JavassistProxyFactory使用了javassist包生成class文件。