什么时候在asm中调用ClassVisitor的visitMethod?
When A ClassVisitor's visitMethod will be called in asm?
假设我 class 是这样的:
public class ClassPrinter extends ClassVisitor {
public ClassPrinter(ClassWriter writer) {
super(Opcodes.ASM5, writer);
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
// when this line will get executed?
System.out.println(name);
}
}
现在什么时候调用 visitMethod
?是在 class 加载发生在 Java 时(那是 class 访问者被调用的地方?)还是在 class 对象上调用方法时?
我对此感到困惑。
visitMethod
在您直接或间接呼叫访问者时被调用。这与 JVM 中的 class 加载或执行完全无关。
ASM 使用访问者模式。你传入一个 class 实现你感兴趣的回调,然后你将它传递给类似 ClassNode.accept(cv)
的东西,ClassNode 将自动为 class 的适当部分调用你的所有回调文件。
通常您将 ClassVisitor
链接到 ClassReader
,它读取给定的 class 并触发所有 visit*
方法
ClassReader cr = new ClassReader(className);
cr.accept(new ClassPrinter(), 0);
何时阅读 class(并打印方法名称)完全取决于您。
但是如果你想转换一个class并将其加载到JVM,一种可能是子class ClassLoader
,在你读取 class 的地方,转换它(通过使用 visit*
方法),然后用 ClassWriter
写入它。从一些代码示例中查看 ASM 的 examples
文件夹(例如 Annotations.java
)。
假设我 class 是这样的:
public class ClassPrinter extends ClassVisitor {
public ClassPrinter(ClassWriter writer) {
super(Opcodes.ASM5, writer);
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
// when this line will get executed?
System.out.println(name);
}
}
现在什么时候调用 visitMethod
?是在 class 加载发生在 Java 时(那是 class 访问者被调用的地方?)还是在 class 对象上调用方法时?
我对此感到困惑。
visitMethod
在您直接或间接呼叫访问者时被调用。这与 JVM 中的 class 加载或执行完全无关。
ASM 使用访问者模式。你传入一个 class 实现你感兴趣的回调,然后你将它传递给类似 ClassNode.accept(cv)
的东西,ClassNode 将自动为 class 的适当部分调用你的所有回调文件。
通常您将 ClassVisitor
链接到 ClassReader
,它读取给定的 class 并触发所有 visit*
方法
ClassReader cr = new ClassReader(className);
cr.accept(new ClassPrinter(), 0);
何时阅读 class(并打印方法名称)完全取决于您。
但是如果你想转换一个class并将其加载到JVM,一种可能是子class ClassLoader
,在你读取 class 的地方,转换它(通过使用 visit*
方法),然后用 ClassWriter
写入它。从一些代码示例中查看 ASM 的 examples
文件夹(例如 Annotations.java
)。