关于ClassReader和accept方法的疑惑

Doubts about the ClassReader and the accept method

我想知道 ASM 用户手册中描述的“优化”是如何工作的。

我从手册中摘录了一小段:

If a ClassReader component detects that a MethodVisitor returned by the ClassVisitor passed as argument to its accept method comes from a ClassWriter, this means that the content of this method will not be transformed, and will in fact not even be seen by the application. In this case the ClassReader component does not parse the content of this method, does not generate the corresponding events, and just copies the byte array representation of this method in the ClassWriter.

更准确地说,我想知道:

  1. MethodVisitorClassWriter 中检索时,ClassReader 不会生成什么事件,而这会被 accept 方法检测到?

  2. 理论上 ClassReader 只是一个事件生产者。 accept 方法真的可以将方法的内容“复制”到作为参数传递的 ClassVisitorClassWriter 或进行任何其他类型的修改吗?

  3. visitMethod方法返回的MethodVisitor真的有用吗?如果是,为了什么?我有这个疑问,因为即使在此方法中返回 null,我的修改也正常发生,没有任何错误。

如果传递ClassReader,ClassWriter可以检测到对应的ClassReader直接发出了一个MethodVisitor。在这种情况下,ASM 不会反序列化和序列化方法,而只是从 class 文件中复制整个方法表示。

包装访问者后,它会返回到反序列化和序列化。

  1. What events does the ClassReader not generate when the MethodVisitor is retrieving from a ClassWriter and this is detected by the accept method?

我们正在谈论 class reader 通常调用的 MethodVisitor 的所有访问…方法。

  1. Theoretically the ClassReader is just an event producer. Can the accept method really "copy" the content of a method to the ClassWriter of a ClassVisitor that was passed as a parameter or make any other type of modification?

要启用此优化,目标 class 的常量池必须与源 class 兼容。为确保这一点,您必须将 ClassReader 传递给 the ClassWriter’s constructor。如果您知道生成的 class 将有足够多的共同点值得这样做,那么您应该这样做。相反,当您有很多重大更改时,这可能会在生成的 class 文件中留下很多未使用的工件。

如果您将 MethodVisitorClassWriter 直接传递给 reader,则应用优化方法,因此您不会对该特定方法进行任何修改。这对所有场景都很有用,您只修改某些方法或不修改任何方法,例如仅添加新方法。

  1. Is the MethodVisitor returned by the visitMethod method really useful for anything? If yes, for what? I have this doubt because even returning null in this method, my modifications occur normally without any kind of error.

你如何应用你的修改?生成具有属性的可执行代码或方法的唯一方法是直接或间接使用由 ClassWritervisitMethod 编辑的 MethodVisitor return。当你不 return 任何 MethodVisitornull 到 reader 时,它不会调用任何方法,因此不会复制任何原始工件。如果您删除或替换整个方法,这可能很有用,但如果您想保留属性和代码,只注入一些新的属性或代码,则没有用。而且,由于整个讨论都是关于,当您将作者的 MethodVisitor 直接传递给 reader 时,您将在生成的 class 文件中重现原始方法,这是否已完成优化与否。