Java 字节码操控框架ASM(一):创建class文件

1、什么是 ASM ?

ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。

2、Java 字节码小知识

a、类型描述符
Java 字节码类型描述符
b、方法描述符
方法描述符

3、创建class文件

首先去官网下载一下jar包:http://forge.ow2.org/project/download.php?group_id=23&file_id=21558
接下来看代码:

package com.asm.createclass;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by ouer1994 on 2017/2/18.
 */

/*
     package pkg;
     public interface Comparable extends Mesurable {
        int LESS = -1;
        int EQUAL = 0;
        int GREATER = 1;
        int compareTo(Object o);
     }
 */
public class GenerateClass {
    public static void main(String args[]) {
        ClassWriter classWriter = new ClassWriter(0);
        // 创建类的头 public interface Comparable extends Mesurable
        // param 1: Java 版本
        // param 2: public abstract interface
        // param 3: 全路径类名
        // param 4: 泛型
        // param 5: 父类,接口隐式继承自Object
        // param 6: 接口数组
        classWriter.visit(Opcodes.V1_8,
                Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT + Opcodes.ACC_INTERFACE,
                "com/asm/createclass/Comparable", null, "java/lang/Object", new String[]{"com/asm/createclass/Mesurable"});
        // 创建 int LESS = -1;
        // param 1: public static final
        // param 2: 字段名称
        // param 3: 字段类型
        // param 4: 泛型
        // param 5: 字段的值
        // 由于这里没有注释,我们立即调用返回FieldVisitor的visitEnd方法,没有调用visitAnnotation或visitAttribute方法。
        classWriter.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "LESS", "I", null, new Integer(-1)).visitEnd();
        classWriter.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "EQUAL", "I", null, new Integer(0)).visitEnd();
        classWriter.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "GREATER", "I", null, new Integer(1)).visitEnd();
        classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "compareTo", "(Ljava/lang/Onbject;)I", null, null).visitEnd();
        classWriter.visitEnd();
        byte[] data = classWriter.toByteArray();
        try {
            FileOutputStream fos = new FileOutputStream(new File("Comparable.class"));
            fos.write(data);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 使用创建好的class文件
        Class clazz = new MyClassLoader().defineClass("com.asm.createclass.Comparable", data);
        try {
            Field field = clazz.getField("LESS");
            Integer o = (Integer) field.get(null);
            System.out.println(o.intValue()); // 输出-1

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
       }
    }

    static class MyClassLoader extends ClassLoader {
    public Class defineClass(String name, byte[] bytes) {
        return defineClass(name, bytes, 0, bytes.length);
    }
}
}

运行代码之后会创建一个 【Comparable.class】 文件。你可以使用IntellJ来查看,发现和我们预期的效果一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

outer199

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值