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

来源:互联网 发布:唐山技术支持盘古网络 编辑:程序博客网 时间:2024/04/29 16:49

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
原创粉丝点击