2015-06-19 11 views
2
System.out.println("A read operation on a field is encountered "); 

Как я могу добавить заявление, позволяет сказать, приведенное выше утверждение, всякий раз, когда операция чтения была выполнена на нелокального поля? , а также мне нужно знать подробности о поле, которое читается и множество деталей должно соответствовать уникальности поляДобавление заявления с использованием Javassist

Пример (для удаления абстракции в вопросе):

public class Greet{ 
    int knowncount; 
    public Greet() 
    { 
     System.out.println("Hello"); 
     knowncount++; 
    } 
    public Greet(String language) 
    { 
    if(String.equals("ENGLISH")) {System.out.println("Hello"); knowncount++; } 
    else if(String.equals("SPANISH")) {System.out.println("Hola"); knowncount++;} 
    else System.out.println("Language not recognized"); 
    } 

    public void showCount() 
    { 
    System.out.println("count : "+knowncount); 
    } 

} 

и тестовый класс пользователя:

class test{ 
    public static void main(String[] args){ 
    Greet g("SPANISH"); 
    g.showCount(); 

    } 

} 

в приведенном выше примере после использования Javassist нашего кода должны вывести:

A read operation on a field is encountered 
1 
+0

Вам нужно показать больше усилий. Либо покажите попытку и объясните проблему с ней, либо сообщите нам, что вы не понимаете о «добавлении инструкции с помощью javaassist *». Ваш вопрос в настоящее время слишком широк. –

+0

@VinceEmigh: Я добавил пример, чтобы проиллюстрировать то же самое, пройдите через него и сообщите мне, сохраняется ли широта –

+0

. Вы можете писать ключевые слова, такие как 'public' и' class', с заглавной буквой в «JavaAssist»?(Я не знаю, что библиотека) – Tom

ответ

2

Вы можете сделать то, что вы просите, используя Javassist's ExprEditor. ExprEditor позволяет редактировать то, что делается в FieldAccess, чтобы реализовать свой запрос можно создать инжектор, который делает следующее:

ClassPool classPool = ClassPool.getDefault(); 
CtClass greetCtClass = classPool.get(Greet.class.getName()); 

greetCtClass.instrument(new ExprEditor() { 
     @Override 
     public void edit(FieldAccess fieldAccess) 
       throws CannotCompileException { 
      if (fieldAccess.getFieldName().equals("knowncount")) { 
       fieldAccess 
         .replace(" { System.out.println(\"A read operation on a field is encountered \"); $_ = $proceed($$); } "); 
      } 
     } 
    }); 

    greetCtClass 
      .writeFile("<ROOT DIRECTORY WHERE THE CLASSES ARE>"); 

Лучший способ объяснить параметр является с примером, представьте, что Приветствуйте класс (что происходит быть в greatPackage) находится по следующему пути /home/user/dev/proj1/build/greetPackage/Greet.class. В этом случае ваш корневой каталог будет /home/user/dev/proj1/build/.

Линия интереса всех котельного листового металла выше является следующее:

{ System.out.println(\"A read operation on a field is encountered \"); $_ = $proceed($$); }

Что здесь происходит?

  • Первое уведомление, что всего код между фигурными скобками, если вы знаете свой путь в Javassist это что-то тривиальное к вам, если не может заставить вас потерять несколько минут, пытаясь понять, что это неправильно.
  • Тогда у вас есть System.out вы просили
  • Наконец у вас есть волшебной линии: $_ = $proceed($$);. Вы можете найти дополнительную информацию об этом в javassist tutorial (ищите FieldAccess в этом разделе, так как у них нет прямого якоря для этого, извините!), Но в основном то, что говорит эта строка, заключается в том, что результирующее значение доступа к полю значение виртуального метода, который вызывается для доступа к полю, так, другими словами, фактическое значение поля.

Имейте в виду, что вы должны переписать свой класс Greet с инжектором в отдельном процессе JVM и только после этого вы будете иметь возможность использовать класс с нагнетаемой поведением, если вы не будете делать некоторые трюки с загрузки классов в убедитесь, что вы загрузили измененную версию. Я не буду входить в эти темы, потому что это выходит за рамки, но если вам нужна помощь в этом, пожалуйста, скажите это. Я с радостью поможем вам.

+0

Спасибо за ваш ответ. Это очень полезно. Я сделал необходимые трюки, чтобы загрузить измененную версию, и теперь она отлично работает. –

+0

@percy: рад, что я мог бы помочь. Помните, что если вы найдете этот ответ полезным, и он решил вашу проблему, чтобы принять его (и повысить его), поэтому он больше не является открытым вопросом. – pabrantes