首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在运行时在renaming方法中重命名字段(java插装)

在运行时在renaming方法中重命名字段(java插装)
EN

Stack Overflow用户
提问于 2014-11-04 14:09:46
回答 1查看 1.8K关注 0票数 6

我想在运行时重命名java类中的字段。此外,任何访问该字段的方法;它是读还是写;我需要修改它以使用新名称而不是旧名称.

所有这一切都将在前主要方法中完成.

作为一个示例,给出以下代码:

代码语言:javascript
复制
public class Class1
{
    String strCompany;

    public String Test()
    {
         strCompany = "TestCompany";
         return strCompany;
    }
}

在上面的类中,我需要将"strCompany“字段更改为"strCompany2",此外,我还需要方法测试来使用新名称而不是旧名称.

可以使用来自setName类的ctField方法来更改字段名,但如何修改方法主体以使用新名称。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-28 17:48:32

嗯,我很晚才知道答案,但我希望你仍然觉得它有用(或者至少有人需要这样的东西)。

尽管您可以使用注释中建议的低级别字节码api,但javassist确实允许您使用更高级别的API (我推荐的API)来实现。

下面我将介绍的解决方案将更改字段名,并将所有引用从旧的字段名更改为新的字段名,这可能是您想要的结果,因为您要重命名该字段。

密码

让我们使用您的Class1示例。

代码语言:javascript
复制
  ClassPool classpool = ClassPool.getDefault();
  CtClass ctClass = classpool.get(Class1.class.getName());
  CtField field = ctClass.getField("strCompany");
  CodeConverter codeConverter = new CodeConverter();
  codeConverter.redirectFieldAccess(field, ctClass, "strCompany2");
  ctClass.instrument(codeConverter);

  field.setName("strCompany2");
  ctClass.writeFile("./injectedClasses");

访问CtField并设置它的名称--由于您的问题--您已经知道如何做了。关于“重新布线”所有字段引用的技巧是使用一个CodeConverter来完成的,它将替换对CtField 字段的所有引用,用于对ctClass中名为strCompany2的字段的引用(这恰好是同一个类)。请记住,在将字段重命名为strCompany2之前,需要先完成此操作。

在这次运行的最后,您将在injectedClasses文件夹中准备好使用strCompany2而不是strCompany。:-)

侧纹

请记住,CodeConverter真正做的是在类常量池中创建一个新条目,并将有关旧字段的所有引用重新路由到定义“新”(read重命名)字段的条目。

因此,在Class1示例中,下面是发生的情况:

注入前常池

代码语言:javascript
复制
Constant pool:
#1 = Class              #2             //  test/Class1
#2 = Utf8               test/Class1
#3 = Class              #4             //  java/lang/Object
#4 = Utf8               java/lang/Object
#5 = Utf8               strCompany
#6 = Utf8               Ljava/lang/String;
#7 = Utf8               <init>
#8 = Utf8               ()V
#9 = Utf8               Code
#10 = Methodref          #3.#11         //  java/lang/Object."<init>":()V
#11 = NameAndType        #7:#8          //  "<init>":()V
#12 = Utf8               LineNumberTable
#13 = Utf8               LocalVariableTable
#14 = Utf8               this
#15 = Utf8               Ltest/Class1;
#16 = Utf8               test
#17 = Utf8               ()Ljava/lang/String;
#18 = String             #19            //  TestCompany
#19 = Utf8               TestCompany
#20 = Fieldref           #1.#21         // test/Class1.strCompany:Ljava/lang/String;
#21 = NameAndType        #5:#6          //  strCompany:Ljava/lang/String;
#22 = Utf8               SourceFile
#23 = Utf8               Class1.java

注入后恒定池

代码语言:javascript
复制
Constant pool:
#1 = Class              #2             //  test/Class1
#2 = Utf8               test/Class1
#3 = Class              #4             //  java/lang/Object
#4 = Utf8               java/lang/Object
#5 = Utf8               strCompany
#6 = Utf8               Ljava/lang/String;
#7 = Utf8               <init>
#8 = Utf8               ()V
#9 = Utf8               Code
#10 = Methodref          #3.#11         //  java/lang/Object."<init>":()V
#11 = NameAndType        #7:#8          //  "<init>":()V
#12 = Utf8               LineNumberTable
#13 = Utf8               LocalVariableTable
#14 = Utf8               this
#15 = Utf8               Ltest/Class1;
#16 = Utf8               test
#17 = Utf8               ()Ljava/lang/String;
#18 = String             #19            //  TestCompany
#19 = Utf8               TestCompany
#20 = Fieldref           #1.#21         // test/Class1.strCompany:Ljava/lang/String; 
#21 = NameAndType        #5:#6          //  strCompany:Ljava/lang/String;
#22 = Utf8               SourceFile
#23 = Utf8               Class1.java
#24 = Utf8               strCompany2
#25 = NameAndType        #24:#6         //  strCompany2:Ljava/lang/String;
#26 = Fieldref           #1.#25         //test/Class1.strCompany2:Ljava/lang/String;

在这种情况下,使用单个字段重写您的constantPool增长了3帧,它们代表了新字段的定义。通常这不是一个问题,但我宁愿提前提及。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26737226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档