1

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


}

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

4

2 回答 2

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字段初始化程序运行之前。

于 2012-12-29T15:41:43.530 回答
1

所有代码都在方法内部(构造函数和静态初始化器也是方法)。

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

private String aString = "A String Value";

//zero argument constructor
public Example(){

}

是相同的

private String aString;

//zero argument constructor
public Example(){
    super();
    aString = "A String Value";
}
于 2012-12-29T15:40:48.687 回答