基于Java字节码技术,如ASM、Javassist,前者偏底层、构建复杂,但性能相对较高;后者提供了友好的API接口方法,优雅简单,但性能稍弱。
本文基于Javassist,初探性以创建一个简单的类、里面创建一个普通属性以及一个静态属性为示例:
引入Maven依赖
<dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.30.2-GA</version>
</dependency>
示例代码
import com.google.gson.Gson;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtNewMethod;public class DynamicPropertyExampleJavassist {public static void main(String[] args) throws Exception {
// 创建一个类池ClassPool pool = ClassPool.getDefault();// 创建一个新的类(完全限定的类型)CtClass cc = pool.makeClass("com.mc.User");// 添加接口cc.setInterfaces(new CtClass[] {pool.makeInterface("java.io.Serializable")});// 添加静态属性并赋值cc.addField( CtField.make("private static final long serialVersionUID = 1L;", cc));// 添加新的属性CtField newField = CtField.make("private String username;", cc);cc.addField(newField);// 添加属性username的 Getter和Setter方法cc.addMethod(CtNewMethod.setter("setUsername", newField));cc.addMethod(CtNewMethod.getter("getUsername", newField));// 将CtClass转换为Class对象Class<?> clazz = cc.toClass();System.out.println("clazz: " + clazz.getName());System.out.println("package: " + clazz.getPackage());// 反射创建一个对象Object obj = clazz.newInstance();System.out.println("obj: " + obj);// 使用Setter方法设置新属性值clazz.getMethod("setUsername", String.class).invoke(obj, "张三");// 使用Getter方法获取新属性值并打印System.out.println("New Property: " + clazz.getMethod("getUsername").invoke(obj));// 转为JSON字符串System.err.println(new Gson().toJson(obj));}
}
结果: