Ну, я опоздал с ответом, но я надеюсь, что вы все еще найдете его полезным (или, по крайней мере, кому-то еще нужны подобные вещи).
Несмотря на то, что вы можете использовать API-интерфейс байт-кода низкого уровня, такой как Raphw, предложенный в комментарии, javassist позволяет вам делать это с API более высокого уровня (что я рекомендую).
Решение, которое я представлю ниже, изменит имя поля и изменит все ссылки со старого имени поля на новое, что, вероятно, в любом случае вам нужно, поскольку вы переименовываете поле. .
Код
Давайте используем ваш пример Class1.
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 ссылками на поле с именем strCompany2 в ctClass (которое оказывается тем же класс). Имейте в виду, что это необходимо сделать до переименования поля в strCompany2.
В конце этого запуска у вас будет новый класс Class1 в папке InjectedClasses, готовый использовать strCompany2 вместо strCompany. :-)
Примечание
Имейте в виду, что на самом деле CodeConverter создает новую запись в пуле констант класса и перенаправляет все ссылки из записи, касающейся старого поля, в ту, которая определяет «новое» (читай переименованное) поле.
Итак, в примере Class1 происходит следующее:
Постоянный пул ДО закачки
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
Постоянный пул ПОСЛЕ инъекции
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 кадра, которые представляют определение нового поля. Обычно это не проблема, но тем не менее я предпочитаю упоминать об этом заранее.
person
pabrantes
schedule
28.11.2014