Java中使用ASM字节码重命名方法理解困难

Java中使用ASM字节码重命名方法理解困难,java,bytecode,bytecode-manipulation,java-bytecode-asm,Java,Bytecode,Bytecode Manipulation,Java Bytecode Asm,我目前正试图了解ASM库是如何工作的。我决定尝试重命名给定类的所有方法,因此我编写了一个迷你methodrenamevisitor: class MethodRenamer extends ClassAdapter { public MethodRenamer(ClassVisitor cv) { super(cv); } @Override public MethodVisitor visitMethod(int access, String

我目前正试图了解ASM库是如何工作的。我决定尝试重命名给定类的所有方法,因此我编写了一个迷你
methodrename
visitor:

class MethodRenamer extends ClassAdapter {
    public MethodRenamer(ClassVisitor cv) {
        super(cv);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        MethodVisitor methodVisitor = cv.visitMethod(access, name+"_new", desc, signature, exceptions);         
        return methodVisitor;
    }
}
事实上,它帮我完成了全部工作,但我不明白为什么。我认为对于给定的代码,它只会为每个方法
m
,创建一个
m新的
方法,没有代码。但与我的预期相反,它以某种方式用原始代码填充每个新的
m\u


这怎么会发生?我的想法是,只有我转发给
cv
的内容才会写入输出文件。我在任何地方都不会告诉你原来的
m
代码是什么,所以我想这里一定有别的事情发生了吧?另一个可行的选择似乎是,它以某种方式使用返回的
methodVisitor

从MethodRename.visitMethod()返回的methodVisitor是ClassReader用来填充方法体的方法。如果您想要一个空方法,那么应该返回null。看。

我第一次也遇到过这个问题

在阅读ASM教程时可能不太清楚,因为有很多概念让你困惑

我有一些建议要你学习

  • 第一,概念
例如:系统提供给您一本书,您需要仔细阅读。你的工作就是写一个阅读这本书的方法。每个人都有自己的阅读方法,也许你想快速阅读,忽略你不感兴趣的章节,也许你想仔细而缓慢地阅读。不管怎样,你的工作就是制定一种方法来实现你如何阅读这本书。然后,将此读取方法提供给系统。系统获取您的方法并执行您在方法中指定的操作。这是一个回调的过程,我想这对你会有很大的帮助

  • 然后,弄清楚这个问题。设计模式在程序中随处可见。我认为ASM框架就是这样工作的

  • 最后,转到ASM教程

附言:

回答
我的课堂阅读者不应该只阅读吗?

尽管它被命名为“ClassReader”,但它的工作并不局限于读取字节码。它将通过其他类调用其他方法,就像MethodVisitor负责方法中的工具字节码一样。这里的方法访问者只是一个回调


ASM框架可以帮助您更改字节码,远离字节码的细节。

但我不明白。我的班级读者不应该只阅读吗?我以为只有转发给班级编剧的东西才会写东西。或者是类读取器将返回的值发送给我背上的类编写器?我不理解你的问题。但是,请注意,ClassWriter是ClassVisitor的一个实现,它通常位于访问者链的末尾。ClassReader读取字节码并生成事件队列,这些事件被反馈给传递给ClassReader.accept(..)方法的ClassVisitor实例。您可以查看一个旧的ASM教程。API略有变化,但概念仍然相同