gpt4 book ai didi

java - 使用 javassist 修改在类构造函数中使用 getter 和 setter 的字段

转载 作者:行者123 更新时间:2023-11-30 04:34:58 28 4
gpt4 key购买 nike

我正在尝试使用 javassist 修改类构造函数中的以下字段:

Label Label1 = new Label(new StringBuilder().append(user.name));
Label Label2 = new Label(new StringBuilder().append(user.time.toString());

我想在 2 个标签前面添加文本。可以使用 getText() 和 setText() 访问和设置文本。

我怎样才能实现这个目标?

最佳答案

最简单的方法是使用 Java 代码修改构造函数主体的功能,并让 javassist 创建字节码。

所以你可以轻松地执行以下操作:

ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.get("package1.package2.ClassToInject");
/* Notice that in this case I'm going for the default constructor
* If you want another constructor you just have to materialize the CtClass, for
* each parameter and pass them in the CtClass Array
*/
CtConstructor declaredConstructor = ctClass.getDeclaredConstructor(new CtClass[] {});
/* Now that you have your constructor you can use insertAfter(), this means, it
* will be the last thing to be executed in the constructor. We'll rewrite the
* label1 field with our new value. Notice that the string in insertAfter
* argument is a regular, valid java code line.
*/
declaredConstructor.insertAfter("Label1 = new package3.package4.Label(new StringBuilder().append(\"somePrefixMayBeAStringOrAVariableInScope\").append(user.name));");

// and finally we write the bytecode
ctClass.writeFile("/somePathToPutTheInjectedClassFile/");

另请记住,如果您要添加的前缀(而不是字符串)是其他类中的静态字段,则您必须提供该类的完整限定名称,例如: .append(package1. package2.SomeClass.SomeField)

这是必需的,因为导入仅在源代码级别,当您查看 JVM 字节码时,所有类引用都是完整限定名称。

有关如何使用 Javassist 实现此类修改的更多信息,请参阅 javasssist 文档的 4.1 Inserting source text at the beginning/end of a method body 部分。

更新

每当您为 javassist 编写要注入(inject)的 Java 代码时,请记住,您必须使用完全限定的类名,否则 javassist 的类池将无法找到类,从而导致 javassist.CannotCompileException.

关于java - 使用 javassist 修改在类构造函数中使用 getter 和 setter 的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13715986/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com