【问题标题】:javassist: Rename classes and Fields typesjavassist:重命名类和字段类型
【发布时间】:2017-03-22 21:31:00
【问题描述】:

我正在开发一个需要检测类的项目。我正在使用javassist,因为在我的情况下进行检测非常方便。

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

假设第 1 类:

public class Class1 {
    Class2 class2;
}

第二类:

public class Class2 {
    //Code
}

还有一个从定义的类中获取CtClasses 并进行一些代码转换的函数。

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.
    }

因为,我正在重命名类,所以 Class1 中的字段 Class2 class2 的类型为 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 描述重命名字段,但不输入。

【问题讨论】:

  • 请注意,我总是附加“_V1”或“_V2”。所以,如果你帮我重命名“LClass1_V1”或“LClass1_V2”就足够了。
  • 能不能不完全删除字段,然后用新名称和新类型添加一个新字段?
  • 我可以,但是删除然后添加和使用'setType()'没有区别

标签: java classloader instrumentation javassist


【解决方案1】:

根据Javassistdocumentation:

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

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");

【讨论】:

  • 我正在重命名class2,但class1 有一个class2 类型的字段,您所指的方法无法重命名class1 中的类型。
猜你喜欢
  • 2012-05-20
  • 1970-01-01
  • 2016-01-04
  • 1970-01-01
  • 1970-01-01
  • 2022-12-31
  • 2012-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多