ASM-Helloworld

本文介绍ASM库的使用方法,演示如何通过ASM创建并执行一个简单的Java类,包括生成构造方法和main方法的字节码指令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AMS使用指南
实战java虚拟机

ASM是一款java字节码的操作库,它在java领域是赫赫有名的函数库。不少著名的软件都依赖该库进行字节码操作。不少著名的软件都依赖该库进行字节码操作。比如,AspectJ,Clojure,Eclipse,spring以及CGLIB都是ASM的使用者。

引入ASM
可以到http://asm.objectweb.org/官方下载,
也可以直接引入maven依赖:

 <dependency>
    <groupId>org.ow2.asm</groupId>
     <artifactId>asm-all</artifactId>
     <version>5.0.2</version>
 </dependency>

ASM体系结构
这里写图片描述


HelloWorld

public class AsmHelloWorld extends ClassLoader implements Opcodes {
    public static void main(String[] args) throws IOException, InvocationTargetException, IllegalAccessException {
        //定义一个叫做Example的类
        ClassWriter cw = new ClassWriter(0);
        cw.visit(V1_6, ACC_PUBLIC, "Example", null, "java/lang/Object", null);

        //生成默认的构造方法
        MethodVisitor mw = cw.visitMethod(ACC_PUBLIC,"<init>","()V",null,null);

        //生成构造方法的字节码指令
        mw.visitVarInsn(ALOAD, 0);
        mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        mw.visitInsn(RETURN);
        mw.visitMaxs(1, 1);
        mw.visitEnd();

        //生成main方法 : public static void main(String args[]);
        mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,"main","([Ljava/lang/String;)V",null,null);

        //生成main方法中的字节码指令: System.out.println("hello world")
        mw.visitFieldInsn(GETSTATIC,"java/lang/System","out","Ljava/io/PrintStream;");

        mw.visitLdcInsn("Hello world!");
        mw.visitMethodInsn(INVOKEVIRTUAL,"java/io/PrintStream","println","(Ljava/lang/String;)V");
        mw.visitInsn(RETURN);
        mw.visitMaxs(2, 2);

        //字节码生成完成
        mw.visitEnd();

        // 获取生成的class文件对应的二进制流
        byte[] code = cw.toByteArray();


        //将二进制流写到本地磁盘上
        FileOutputStream fos = new FileOutputStream("Example.class"); //磁盘上生成Example.class文件
        fos.write(code);
        fos.close();

        //直接将二进制流加载到内存中
        AsmHelloWorld loader = new AsmHelloWorld();
        Class<?> exampleClass = loader.defineClass("Example", code, 0, code.length);

        //通过反射调用main方法
        exampleClass.getMethods()[0].invoke(null, new Object[]{null});

    }
}

解析

使用javap -v Example

public class Example
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC
Constant pool:
  //...............略
{
  public Example();
    descriptor: ()V                   ####无参构造函数
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: return

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #18                 // String Hello world!
         5: invokevirtual #24                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值