Как программно получить доступ к закрытым членам через привилегированный аспект в AspectJ? - PullRequest
0 голосов
/ 02 декабря 2009

Мне было интересно, возможно ли в AspectJ сделать следующее. Я добавляю метод .inspect () к каждому объекту класса RubyObject. Предполагается, что этот метод выплевывает строку вроде # (CompleteClassName, var1 = val1, var2 = val2,…)

Пока все хорошо, this.getClass (). GetFields () возвращает мне все видимые поля, которые я хочу, и this.getClass (). GetDeclaredFields () в сочетании с Modifier.isPrivate (field.getModifiers ())) дает мне список всех приватных полей ..

Проблема здесь в том, что я не могу получить значение полей приват, как я это делал с видимым. Полагаю, это нормально, поскольку используемый мной отражающий API не является частью AspectJ, поэтому они не знают, что я использую здесь так называемый привилегированный аспект.

Поскольку я нахожусь в привилегированном режиме, я могу получить доступ ко всем закрытым переменным, которые я хочу, используя this.privateVariableName, но как я могу сделать это программно, когда имя переменной само находится в переменной?

Спасибо за вашу помощь ..

public privileged aspect Reflect {
 private static HashMap<Class<? extends Object>,ArrayList<RubyObject>> oStore = new HashMap<Class<? extends Object>, ArrayList<RubyObject>>();

 private boolean RubyObject.hasBeenImported = false;
 declare parents: ca.concordia.* implements RubyObject;


 //inspect return a string of the format #<classname, var1=val, var2=val, ...>
 //Unfortunately, it doesn't get PRIVATE data since privileged aspect can't gelp with field.get(Object)
 public String RubyObject.inspect()
 { String result = "#<" + this.getClass().getName();
  for (Field field : this.getClass().getFields())
  { 
    try { result += ", " + field.getName() + "=" + field.get(this); }
    catch(Exception e) { result += ", " + field.getName() + "=(???)"; }  //should never occur;
  }
  for (Field field : this.getClass().getDeclaredFields())
  { if (Modifier.isPrivate(field.getModifiers()))
    result += ", " + field.getName() + "=(PRIVATE)"; 
  }
  result += ">";
  return result;
 }

1 Ответ

1 голос
/ 30 апреля 2012

У меня была такая же проблема, и кажется, что это так же просто, как изменить

result += ", " + field.getName() + "=(PRIVATE)"; 

до

field.setAccessible(true);
result += ", " + field.getName() + "="+ field.get(this);

Надеюсь, это кому-нибудь поможет!

...