cc2链

javassist学习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import javassist.*;

import java.lang.reflect.Method;
/*
javassist使用
主要类
ClassPool:基于哈希表实现的CtClass对象容器,键名是类名称,值是该类CtClass对象
常用方法:
static ClassPool getDefault()
返回默认的类池。
ClassPath insertClassPath(java.lang.String pathname)
在搜索路径的开头插入目录或jar(或zip)文件。
ClassPath insertClassPath(ClassPath cp)
ClassPath在搜索路径的开头插入一个对象。
java.lang.ClassLoader getClassLoader()
获取类加载器toClass(),getAnnotations()在 CtClass等
CtClass get(java.lang.String classname)
从源中读取类文件,并返回对CtClass 表示该类文件的对象的引用。
ClassPath appendClassPath(ClassPath cp)
将ClassPath对象附加到搜索路径的末尾。
CtClass makeClass(java.lang.String classname)
创建一个新的public类


CtClass类;
常用方法
void setSuperclass(CtClass clazz)
更改超类,除非此对象表示接口。
java.lang.Class<?> toClass(java.lang.invoke.MethodHandles.Lookup lookup)
将此类转换为java.lang.Class对象。
byte[] toBytecode()
将该类转换为类文件。
void writeFile()
将由此CtClass 对象表示的类文件写入当前目录。
void writeFile(java.lang.String directoryName)
将由此CtClass 对象表示的类文件写入本地磁盘。
CtConstructor makeClassInitializer()
制作一个空的类初始化程序(静态构造函数)。
CtMethod
CtMethod:表示类中的方法。


CtConstructor
CtConstructor的实例表示一个构造函数。它可能代表一个静态构造函数(类初始化器)。
*/


//使用javassis来创建一个Person类
public class CreatClass {
public static void main(String[] args) throws Exception {
//获取javassist维护的类池
ClassPool pool = ClassPool.getDefault();
//创建一个空类
CtClass ctClass = pool.makeClass("Person");
//给ctClass类即public类添加一个string类型的字段
CtField name = new CtField(pool.get("java.lang.String"), "name",ctClass);
//设置private权限
name.setModifiers(Modifier.PRIVATE);//CtField类setModifiers方法 arg:Modifier类字段返回int类型
//初始化name字段为张三
ctClass.addField(name, CtField.Initializer.constant("zhangsan"));//CtClass类addField方法 args1:CtField对象,args2:内部静态Initializer类对象
//生成get,set方法
ctClass.addMethod(CtNewMethod.getter("getName", name));//addMethod方法 args1:方法名,args2:CtField对象
ctClass.addMethod(CtNewMethod.setter("setname",name));
//添加无参构造参数
CtConstructor ctConstructor0 = new CtConstructor(new CtClass[]{}, ctClass);
ctConstructor0.setBody("{name=\"xiaoming\";}");
ctClass.addConstructor(ctConstructor0);
//添加有参构造参数
CtConstructor ctConstructor1 = new CtConstructor(new CtClass[]{pool.get("java.lang.String")}, ctClass);
ctConstructor1.setBody("{$0.name=$1;}");//设置函数构造主体,$1表示的第一个参数
ctClass.addConstructor(ctConstructor1);
//创建一个public方法printName()无参无返回值
CtMethod printName = new CtMethod(CtClass.voidType, "PrintName", new CtClass[]{}, ctClass);//构造方法args1:函数返回类型,函数名,无参,类名
printName.setModifiers(Modifier.PUBLIC);//设置public
printName.setBody("{System.out.println($0.name);}");//设置函数体
ctClass.addMethod(printName);


//写入class文件
ctClass.writeFile();
ctClass.detach();


/* //通过反射调用person类的方法
Object o = ctClass.toClass().newInstance();
Method setname = o.getClass().getMethod("setname", String.class);
setname.invoke(o, "hungry");
Method printname = o.getClass().getMethod("PrintName");
printname.invoke(o);
*/
//通过加载class文件
}
}

Read More