有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java 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) 个答案

  1. # 1 楼答案

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

  2. # 2 楼答案

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

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

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

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