javassist:重命名类和字段类型

时间:2017-03-22 21:31:00

标签: java classloader instrumentation javassist

我正在开发一个需要类的工具的项目。我正在使用javassist因为在我的情况下做仪器非常方便。

我遇到了一个问题,可以使用以下代码段来描述:

假设第1类:

public class Class1 {
    Class2 class2;
}

第2课:

public class Class2 {
    //Code
}

一个函数,用于从定义的类中获取CtClass es并进行一些代码转换。

public void testFunction() throws NotFoundException {
        ClassPool classPlool;
        classPlool = ClassPool.getDefault();
        CtClass ctCls1 = classPlool.getAndRename("Class1", "Class1_V1");
        // instrument and load ctCls1 etc.
        CtClass ctCls2 = classPlool.getAndRename("Class2", "Class2_V1");
        // instrument and load ctCls1 etc.
    }

因为,我正在重命名这些类,因此Class2 class2中的字段Class1的类型为class Class2,但该类已重命名为Class2_V1。我还要将字段类型从LClass2重命名为LClass2_V1

ctCls1是:javassist.CtClassType@3b9a45b3[changed public class Class1_V1 fields=Class1_V1.class2:LClass2;, constructors=javassist.CtConstructor@568db2f2[public Class1_V1 ()V], methods=]

PS:我要用不同的工具加载两个版本的类,所以这是我案例中最好的方法。此外,我已经搜索了这个问题,但没有解决方案,就像this link描述的那样重命名字段,而不是类型。

1 个答案:

答案 0 :(得分:1)

根据Javassist documentation

可以将新类定义为现有类的副本。下面的程序可以做到:

ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("Point");
cc.setName("Pair");

该程序首先获取Point类的CtClass对象。

然后调用setName()为该CtClass对象提供一个新名称Pair。

在此调用之后,由CtClass对象表示的类定义中出现的所有类名都将从Point更改为Pair。类定义的另一部分不会改变。

修改 要在类中重命名字段类型,您可以导航该类并通过Javassist类型CtField

进行操作
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("Class1");
CtField cf = cc.getField("class2NameIntoClass1");
CtClass cc2 = cf.getType();
cc2.setName("Class2NewName");