javassist
<!-- https://mvnrepository.com/artifact/javassist/javassist -->
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
package com.noob;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.NotFoundException;
import lombok.Data;
import com.zhongan.fcp.pre.allin.common.utils.JSONUtils;
public class TestJavassist {
public static void main(String[] args) {
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream readIn = new ObjectOutputStream(bo);
readIn.writeObject(modifyClass());
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream writeOut = new ObjectInputStream(bi);
A b = A.class.cast(writeOut.readObject()); // 反序列化对象类型是序列化对象的父类或本身
System.out.println(JSONUtils.toFormatJsonString(b));
System.out.println(b.getA());
} catch (Exception e) {
e.printStackTrace();
}
}
private static Object modifyClass() throws NotFoundException,
CannotCompileException, IntrospectionException,
InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
ClassPool pool = ClassPool.getDefault();
// 获取一个A类的CtClass对象
CtClass ctClass = pool.get("com.noob.A");
// 为ctClass设置一个父类
ctClass.setSuperclass(pool.get("com.noob.B"));
// 为cTclass对象添加一个属性name
ctClass.addField(CtField.make("private String addField;", ctClass));
ctClass.addMethod(CtMethod
.make("public void setAddField(String addField){this.addField = addField;}",
ctClass));
ctClass.addMethod(CtMethod.make(
"public String getAddField(){return this.addField;}", ctClass));
ctClass.removeField(ctClass.getDeclaredField("a"));
ctClass.removeMethod(ctClass.getDeclaredMethod("getA"));
ctClass.removeMethod(ctClass.getDeclaredMethod("setA"));
// 获取ctClass对象对应的Class对象cls
Class cls = ctClass.toClass();
// 对cls类进行内省,得到对象BeanInfo
BeanInfo beanInfo = Introspector.getBeanInfo(cls, Object.class);
// 获取beanInfo的方法描述对象
MethodDescriptor[] descriptors = beanInfo.getMethodDescriptors();
for (int i = 0; i < descriptors.length; i++) {
System.out.println("--- modify class method:----"
+ descriptors[i].getName());
}
PropertyDescriptor[] propertyDescriptors = beanInfo
.getPropertyDescriptors();
for (int i = 0; i < propertyDescriptors.length; i++) {
System.out.println("--- modify class field:----"
+ propertyDescriptors[i].getDisplayName());
}
System.out.println("-------------------------------");
for (Method method : A.class.getDeclaredMethods()) {
System.out.println("---after modify A.class method----"
+ method.getName());
}
for (Field field : A.class.getDeclaredFields()) {
System.out.println("---after modify A.class field----"
+ field.getName());
}
Object obj = cls.newInstance();
for (Method method : cls.getDeclaredMethods()) {
if (method.getName().startsWith("set")) {
method.invoke(obj, "test" + method.getName());
}
}
return obj;
}
}
@Data
class A implements Serializable {
private static final long serialVersionUID = 1L;
private String a, b, c;
}
@Data
class B implements Serializable {
private static final long serialVersionUID = 1L;
private String d, e, f;
}
【新增 字段、方法】
【删除 字段、方法】