ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ASM:(4)如何编写ASM代码

2022-04-07 18:03:32  阅读:187  来源: 互联网

标签:ClassReader 代码 ASMPrint ASM org 编写 asm


原文:https://lsieun.github.io/java-asm-01/how-to-write-core-code.html

在刚开始学习ASM的时候,编写ASM代码是不太容易的。或者,有些人原来对ASM很熟悉,但由于长时间不使用ASM,编写ASM代码也会有一些困难。在本文当中,我们介绍一个ASMPrint类,它能帮助我们将.class文件转换为ASM代码,这个功能非常实用。

ASMPrint类

下面是ASMPrint类的代码,它是利用org.objectweb.asm.util.TraceClassVisitor类来实现的。在使用的时候,我们注意修改一下classNameparsingOptionsasmCode参数就可以了。

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.util.ASMifier;
import org.objectweb.asm.util.Printer;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceClassVisitor;

import java.io.IOException;
import java.io.PrintWriter;

/**
 * 这里的代码是参考自{@link org.objectweb.asm.util.Printer#main}
 */
public class ASMPrint {
    public static void main(String[] args) throws IOException {
        // (1) 设置参数
        String className = "com.wj.asm.print.HelloWorld";
        int parsingOptions = ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG;
        boolean asmCode = true;

        // (2) 打印结果
        Printer printer = asmCode ? new ASMifier() : new Textifier();
        PrintWriter printWriter = new PrintWriter(System.out, true);
        TraceClassVisitor traceClassVisitor = new TraceClassVisitor(null, printer, printWriter);
        new ClassReader(className).accept(traceClassVisitor, parsingOptions);
    }
}

在现在阶段,我们可能并不了解这段代码的含义,没有关系的。现在,我们主要是使用这个类,来帮助我们生成ASM代码;等后续内容中,我们会介绍到TraceClassVisitor类,也会讲到ASMPrint类的代码,到时候就明白这段代码的含义了。

ASMPrint类使用示例

假如,有如下一个HelloWorld类:

public class HelloWorld {
    public void test() {
        System.out.println("Test Method");
    }
}

对于ASMPrint类来说,其中

  • className值设置为类的全限定名,可以是我们自己写的类,例如com.wj.asm.print.HelloWorld,也可以是JDK自带的类,例如java.lang.Comparable
  • asmCode值设置为truefalse。如果是true,可以打印出对应的ASM代码;如果是false,可以打印出方法对应的Instruction。
  • parsingOptions值设置为ClassReader.SKIP_CODEClassReader.SKIP_DEBUGClassReader.SKIP_FRAMESClassReader.EXPAND_FRAMES的组合值,也可以设置为0,可以打印出详细程度不同的信息。

执行上面的main方法的效果:

image-20220407174803229

功能拆分

上面介绍的ASMPrint类,是一个功能二合一的类,它既可以打印Core API的代码,也可以查看类的内容。 为了方便理解,我们将它拆分成PrintASMCodeCore类和PrintASMTextClass类。

  • PrintASMCodeCore类:打印Core API的代码。
  • PrintASMTextClass类:打印类的内容。

另外,项目当中也提供了PrintASMCodeTree类和PrintASMTextLambda类:

  • PrintASMCodeTree类:打印Tree API的代码。
  • PrintASMTextLambda类:打印Lambda表达式生成的内部类的内容。

总结

本文主要介绍了ASMPrint类和它的使用示例,内容总结如下:

  • 第一点,ASMPrint类,是通过org.objectweb.asm.util.TraceClassVisitor实现的。
  • 第二点,ASMPrint类的作用,是帮助我们生成ASM代码。当我们想实现某一个功能时,不知道如何下手,可以使用ASMPrint类生成的ASM代码,作为思考的起点。

在当前的阶段,我们可能并不了解ASMPrint类里面代码的含义,但是并不影响我们使用它,让它来帮助我们生成ASM代码。

标签:ClassReader,代码,ASMPrint,ASM,org,编写,asm
来源: https://www.cnblogs.com/wwjj4811/p/16113495.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有