博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javassist用法总结
阅读量:5915 次
发布时间:2019-06-19

本文共 3095 字,大约阅读时间需要 10 分钟。

  hot3.png

1.1. Javassist介绍

Javassist是一个开源的分析、编辑和创建Java的类库。的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

1.2. ClassPool

1. pool获取系统路径以及JVM的同路径下的class

ClassPool pool = ClassPool.getDefault();

2. 新建一个空的pool,没有任何路径

ClassPool pool = new ClassPool();

3. 新建一个只有系统路径资源的pool

ClassPool pool = new ClassPool(true);

相当于

ClassPool pool = new ClassPool();pool.appendSystemPath(); //添加系统路径

4. 用另一个ClassPool建立父子关系

ClassPool parent = ClassPool.getDefault();ClassPool child = new ClassPool(parent);

默认情况和classloader的双亲委托机制相同,会先从父类查找

子类的池可以设置childFirstLookup true优先从子类查找

child.childFirstLookup = true; //此时优先子类查找

 

1.3. classpool增加路径的方法

1. 加入文件资源

pool.insertClassPath("文件路径")

5. 加入url资源

ClassPathpool = new URLClassPath("www.javassist.org", 80, "/java/", "org.javassist.");

pool.insertClassPath(cp);

6. 加入数组资源

byte[] b = a byte array;

String name = class name;

pool.insertClassPath(new ByteArrayClassPath(name, b));

7. 加入类资源

pool.insertClassPath(new ClassClassPath(XXX.Class)));

8. 导入包

pool.importPackage("java.awt");

1.4. Ctclass

1. 获取对象

1. 直接从池中获取(推荐)

CtClass cc=pool.get(类名);

2. //可以从输入流中加载class(实际就是重新定义了一个类)

InputStream ins = an input stream for reading a class file;

CtClass cc = pool.makeClass(ins);

注意:使用输入流的形式在加载有继承,组合,依赖,聚合等关系的类时,需要将用到的类都加入才能进行修改等操作,否则会出异常。建议结构简单的类来使用此方法。

3. 定义一个class

       CtClass cc = pool.makeClass("类名");

2. 常用方法

1. writeFile

writeFile()

写入内存,如何对CtClass进行了修改,内存中就是修改后的类

writeFile("文件路径")

此时会将修改后的字节码输出到相应的文件路径上,此方法可以用来查看我们的修改是否和预期相同

2. toClass

toClass()

Class clazz = cc.toClass();

此时由当前线程的classloader加载这个class

Class clazz = cc.toClass(loaderdomain);

指定classloader来加载

 

writeFile(), toClass(), or toBytecode()CtClass对象就被冻结,不允许进行修改需要调用defrost();才能继续修改

 

3. setName

改变类名

cc.setName("Pair");

CtClass对象被冻结后可以通过pool来更改类名

CtClass cc2 = pool.getAndRename("Point", "Pair");

 

CtClasspool对象移除

cc.detach();

 

4. 删除现有元素

removeField,removeMethod,removeConstructor

5. 添加元素

addField,addMethod,addConstructor

2.1. javassist.Loader

  Loader cl = new Loader(pool);

2.2. CtConstructor 

1可以通过Ctclass对象的getConstructor的方法获取已经存在的构造函数

2直接新建CtConstructor ,需要设置访问权限

constructor.setModifiers(Modifier.PUBLIC);  //设置为public

3CtNewConstructormake方法新建或者defaultConstructor方法

CtNewConstructor.make(parameters, exceptions, declaring)

CtNewConstructor.defaultConstructor(arg0)

4调用CtNewConstructorcopy方法复制

setBody()设置方法体

2.3. CtMethod 

1可以通过Ctclass对象的getDeclaredMethod的方法获取已经存在的方法

2直接新建CtMethod 

3通过CtNewMethodmake方法来新建

4调用CtNewMethodcopy方法复制

注意:

通过CtMethod method = new CtMethod(返回类型名字,参数类型CtClass对象);cc.addMethod(method );

此时加入的方法没有方法体,默认是个抽象方法,CtClass对象也变为抽象类

在添加方法之后设置方法体后,需要修改CtClass对象的权限,去掉abstractmethod .setBody("XXX");cc.setModifiers(cc.getModifiers() & ~Modifier.ABSTRACT);

2.4. CtField

1可以通过Ctclass对象的getField的方法获取已经存在的成员变量

2直接新建CtField

3通过CtFieldmake方法来新建

CtClassaddField的方法中可以对新建的成员变量初始化

 

成员函数的修改

增添代码段

insertBefore

都是插入单行语句或者是一个代码块{}

 

before-statements; 原来的内容  after-statements; }

 

 

 

调用方法参数

2.4.1.1. $0, $1, $2, ...    $0表示this,$1表示第一个参数$2表示第二个参数

2.4.1.2. $args 表示 所有参数是一个object[] ,$args[0]表示$1

2.4.1.3. $$   表示所有参数等同与$1 $2 $3……

2.4.1.4. $r  表示方法的返回类型

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/xpbob/blog/534628

你可能感兴趣的文章
手动开启tomacat服务器
查看>>
myeclipse快捷键
查看>>
java中系统中的常量
查看>>
pdf 转成 一张图片
查看>>
Servlet从浅入深
查看>>
面试(Java之IO与NIO)
查看>>
html基础学习
查看>>
windows7安装完上不了网
查看>>
不等式选讲
查看>>
1、单例模式(饿汉/懒汉)
查看>>
各项目意见(第一阶段)
查看>>
uoj#37. 【清华集训2014】主旋律(状压dp+容斥)
查看>>
poj 2888 Magic Bracelet
查看>>
HUD 2534 Score
查看>>
看到的一篇多线程的基础讲解文章,转发过来
查看>>
堡垒机系统
查看>>
使用 CountDownLatch 控制多个线程执行顺序
查看>>
Oracle触发器用法实例详解
查看>>
16.REPL 命令
查看>>
21OGNL与ValueStack(VS)-静态方法访问
查看>>