使用javassist修改在类构造函数中使用getter和setter的字段 [英] Use javassist to modify fields that use getters and setters in a class constructor

查看:113
本文介绍了使用javassist修改在类构造函数中使用getter和setter的字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to modify the following fields in a class constructor using javassist :

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

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

I want to prepend text to the 2 labels. The text can be accessed and set using getText() and setText().

我怎么能做到这一点?

推荐答案

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

The simplest approach is to use the ability to modify the constructor body with java code and let javassist create the bytecode.

因此您可以轻松地执行以下操作:

So you can easily do something like:

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

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

Also keep in mind that if the prefix you'll be adding, instead of a String is a static field in other class you must give the full qualified name of that class, for example: .append(package1.package2.SomeClass.SomeField).

这是必需的,因为 imports 仅在源代码级别,当您查看JVM字节码时,所有类引用都是全限定名.

This is needed because imports are only at source level, when you look at the JVM bytecode all class references are to the full qualified name.

有关如何使用Javassist进行此类修改的更多信息,请参见javasssist的文档中的

More information on how to achieve this kind of modifications with Javassist can be found in the javasssist's documentation, section 4.1 Inserting source text at the beginning/end of a method body

更新

每当编写Java代码以供javassist注入时,请记住必须使用完全合格的类名,否则javassist的类池将无法找到导致 javassist.CannotCompileException .

Whenever you are writing Java code for javassist to inject, keep in mind that you must use full qualified class names, otherwise javassist's classpool wouldn't be able to find the classes resulting in a javassist.CannotCompileException.

这篇关于使用javassist修改在类构造函数中使用getter和setter的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆