2010-11-16 2 views
4

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

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


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

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

person.name = "Joe";

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

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

EDIT

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

+0

post EDIT. Вы можете специально проверить, является ли загружаемый класс Person, и если это так, выберите применение к нему этого инструментария. Это не соответствует вашим требованиям? –

+0

Спасибо, я пытаюсь это выяснить: где я могу поместить байт-код? Существует ли метод, вызываемый классом, когда обращение к одному из его полей? Или мне нужно будет искать все остальные классы, найти экземпляры доступа к полям и заменить их вызовами метода? –

+1

подумал, что я упоминал об этом, но когда поле является частным, но этот класс является внутренним классом другого класса, этот внешний класс может получить доступ к полю напрямую, даже если он является закрытым. Он делает это, создавая синтетический метод доступа к полю. Если вы ограничены этим случаем, вы можете просто изменить синтетический метод, и тогда он работает, как и python. (но в общем случае ответ отрицательный, вы должны изменить обычные методы.) – MeBigFatGuy

ответ

0

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

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

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

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

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

вы можете изменить исходный класс так, как хотите, а затем использовать asmify для генерации кода asm для создания этого преобразования. – MeBigFatGuy