字节码操作以拦截设置字段的值

发布于 2024-10-03 00:09:59 字数 641 浏览 3 评论 0原文

使用像 ASM 或 cglib 这样的库,有没有办法向类添加字节码指令,以便在设置类字段的值时执行代码?

例如,假设我有这个类:


   public class Person
   {  
       bool dirty;
       public String name;
       public Date birthDate;
       public double salary;
   }

假设一段代码包含这一行:

person.name = "乔";

我希望拦截该指令,因此将 dirty 标志设置为 true。我知道这对于 setter 方法是可能的 - person.setName (“Joe”) - 因为类方法可以通过字节码操作进行修改,但我想对 做同样的事情字段

这可能吗?如果可能的话,如何

编辑

我想避免修改访问该类的代码部分,我正在寻找一种方法将拦截代码保留为 Person 类的一部分。是否有类似于 Python 类中的属性的字段访问伪方法?

Using a library like ASM or cglib, is there a way to add bytecode instructions to a class to execute code whenever the value of a class field is set?

For example, let’s say I have this class:


   public class Person
   {  
       bool dirty;
       public String name;
       public Date birthDate;
       public double salary;
   }

Let’s say a section of code contains this line:


person.name = "Joe";

I want this instruction to be intercepted so the dirty flag is set to true. I know this is possible for setter methods -- person.setName (“Joe”) -- as class methods can be modified by bytecode manipulation, but I want to do the same thing for a field.

Is this possible, and if so, how?

EDIT

I want to avoid modifying the code section that accesses the class, I'm looking for a way to keep the interception code as part of the Person class. Are there a pseudo-methods for field access, similar to properties in Python classes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浮生面具三千个 2024-10-10 00:09:59

有两种用于更新字段的字节码:putfieldputstatic(请参见 http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc11.html)。这些可以在使用类的代码中找到,因此无法简单地修改 Person

There are two bytecodes for updating fields: putfield and putstatic (see http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc11.html). These will be found in the code for the using class, so there's no way to simply modify Person.

原谅我要高飞 2024-10-10 00:09:59

简而言之,您需要在感兴趣的方法中注入执行以下操作的字节码:

if (person.name.equals("Joe") { 
   dirty = true;
}

您无法在检测时评估该字段 - 它必须在方法执行时在运行时评估。

关于如何操作的问题,请尝试以下操作:

  • 在测试类中编写代码并生成字节码的 ascii 版本以查看生成的内容。您可以使用javap轻松完成此操作。

In short, you need to inject bytecode that does the following in the method of interest :

if (person.name.equals("Joe") { 
   dirty = true;
}

You cannot evaluate the field at instrumentation time - it has to be at runtime when the method is executing.

Regarding your question of how, try the following:

  • Write the code in a test class and generate an ascii version of the bytecode to see what was generated. You can do this easily with javap.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文