Манипулирование байт-кодом для перехвата установки значения поля - PullRequest
5 голосов
/ 16 ноября 2010

Используя библиотеку, подобную ASM или cglib, есть ли способ добавить инструкции байт-кода в класс для выполнения кода всякий раз, когда установлено значение поля класса?

Например, допустим, у меня есть этот класс:


   public class Person
   {  
       bool dirty;
       public String name;
       public Date birthDate;
       public double salary;
   }

Допустим, часть кода содержит следующую строку:

person.name = "Joe";

Я хочу, чтобы эта инструкция была перехвачена, поэтому флаг dirty установлен на true. Я знаю, что это возможно для методов установки - person.setName (“Joe”) - поскольку методы класса могут быть изменены с помощью манипулирования байт-кодом, но я хочу сделать то же самое для поля .

Возможно ли это, и если да, то как ?

EDIT

Я хочу избежать изменения секции кода, которая обращается к классу, я ищу способ сохранить код перехвата как часть класса Person. Существуют ли псевдо-методы для доступа к полям, аналогичные свойствам в классах Python?

Ответы [ 2 ]

4 голосов
/ 17 ноября 2010

Существует два байт-кода для обновления полей: putfield и putstatic (см. http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc11.html).. Они будут найдены в коде для класса using, поэтому просто невозможно изменить Person.

0 голосов
/ 16 ноября 2010

Короче говоря, вам нужно ввести байт-код, который делает следующее в интересующем методе:

if (person.name.equals("Joe") { 
   dirty = true;
}

Вы не можете оценить поле во время инструментария - оно должно быть во время выполнения, когда метод выполняется.

Что касается вашего вопроса о том, как, попробуйте следующее:

  • Напишите код в тестовом классе и сгенерируйте ascii-версию байт-кода, чтобы увидеть, что было сгенерировано.Вы можете сделать это легко с javap.
...