ASM - перехват доступа к полям за пределами метода

В настоящее время я использую ASM для перехвата всех попыток изменить значения полей в целевом приложении. Это работает, как и ожидалось, поскольку ASM позволяет добавлять или добавлять инструкции к сегментам кода метода или конструктора.

Однако мне пришло в голову, что это довольно распространенная парадигма разработчика для инициализации полей вне области метода или конструктора, например:

public class Example{

  //--VARIABLE INITIALIZATION OUTSIDE METHOD OR CONSTRUCTOR SCOPE ---
  private String aString = "A String Value";

  //zero argument constructor
  public Example(){

  }

  //all other methods.


}

Мой вопрос: как можно подойти к задаче Перехвата доступа к полям, созданной таким образом, то есть вне контекста Метода или Конструктора?

2 ответа

Решение

Похоже, что это за пределами конструктора в исходном коде, но на самом деле в байт-коде все инициализаторы являются частью конструктора (ов) - они "перемещаются" в конструктор компилятором. Инициализаторы размещаются после неявного или явного super() вызов, но до остальной части кода конструктора. В частности это означает, что если у вас есть такая ситуация:

class Super {
  protected Super() {
    doSomeStuff();
  }

  protected abstract void doSomeStuff();
}

class Sub extends Super {
  private int number = 1;

  public Sub() {
    super();
    System.out.println("in Sub(): " + number);
  }

  protected doSomeStuff() {
    System.out.println("in doSomeStuff(): " + number);
  }
}

затем new Sub(); будет печатать

in doSomeStuff(): 0
in Sub(): 1

как in doSomeStuff печать происходит до Sub полевые инициализаторы запустились.

Весь код находится внутри методов (конструкторы и статические инициализаторы также являются методами).

У вас есть начальные значения для полей, которые вы можете увидеть в объявлении поля, но компилятор, кажется, не использует их слишком много.

private String aString = "A String Value";

//zero argument constructor
public Example(){

}

такой же как

private String aString;

//zero argument constructor
public Example(){
    super();
    aString = "A String Value";
}
Другие вопросы по тегам