Java ASM-拦截外部方法进行的现场访问

Java ASM-拦截外部方法进行的现场访问,java,instrumentation,java-bytecode-asm,Java,Instrumentation,Java Bytecode Asm,我目前正在使用ASM截获所有试图在目标应用程序中改变字段值的尝试。由于ASM允许您在方法或构造函数代码段中预先添加或附加指令,因此,这一功能正常工作 然而,我突然想到,初始化方法或构造函数范围之外的字段是一种相当常见的开发人员范例,例如: public class Example{ //--VARIABLE INITIALIZATION OUTSIDE METHOD OR CONSTRUCTOR SCOPE --- private String aString = "A String

我目前正在使用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.


}

我的问题是:如何拦截以这种方式(即在方法或构造函数的上下文之外)进行的字段访问任务?

所有代码都在方法内部(构造函数和静态初始值设定项也是方法)

您可以在字段声明中看到字段的初始值,但编译器似乎没有太多地使用这些值

private String aString = "A String Value";

//zero argument constructor
public Example(){

}

private String aString;

//zero argument constructor
public Example(){
    super();
    aString = "A String Value";
}

在源代码中,这看起来像是在构造函数之外,但实际上在字节码中,初始值设定项都是构造函数的一部分-它们被编译器“移动”到构造函数中。初始值设定项放在隐式或显式
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);
  }
}
然后
newsub()将打印

doSomeStuff()中的
:0
在Sub()中:1

由于doSomeStuff
中的
打印发生在
Sub
字段初始值设定项运行之前。

出于某种原因,我假设这是由某个隐藏的初始值设定项块完成的。感谢您澄清这一点-您当然是正确的。在ASM中,构造函数被称为
(…)V
,静态初始化器块被称为
()V
,我们也非常感谢您对如何在子类上下文中工作的更多见解。非常感谢。