`
jiasky
  • 浏览: 23341 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

ASM DEMO

阅读更多

原文:http://caodaoxi.iteye.com/blog/723910

 

下面这个是用 ASM 工具为 Student 类添加一个 public String 类型的 address 属性:

1,需要添加属性的原始类:Student.java

public class Student {
    private int age;
    private String name;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }   
} 

 2,添加属性的适配器:AddFieldAdapter.java

import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;

public class AddFieldAdapter extends ClassAdapter {
    private int accessModifier;
    private String name;
    private String desc;
    private boolean isFieldPresent;

    public AddFieldAdapter(ClassVisitor cv, int accessModifier, String name, String desc) {
        super(cv);
        this.accessModifier = accessModifier;
        this.name = name;
        this.desc = desc;
    }

    @Override
    public FieldVisitor visitField(int access, String name, String desc,
            String signature, Object value) {
        if (name.equals(this.name)) {
            isFieldPresent = true;
        }
        return cv.visitField(access, name, desc, signature, value);
    }

    @Override
    public void visitEnd() {
        if (!isFieldPresent) {
            FieldVisitor fv = cv.visitField(accessModifier, name, desc, null, null);
            if (fv != null) {
                fv.visitEnd();
            }
        }
        cv.visitEnd();
    }
} 

 3,添加属性的工具 AddField.java

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

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

public class AddField {

    private Class clazz = null;
    private ClassReader cr = null;
    private ClassWriter cw = null;
    private ClassAdapter ca = null;
    private File classFile = null;

    private final static String CLASS_FILE_SUFFIX = ".class";

    public AddField(Class clazz) {
        this.clazz = clazz;
    }

    /**
     * 添加一个 public 的类成员
     * @param fieldName     类成员名
     * @param fieldDesc     类成员类型描述
     */
    public void addPublicField(String fieldName, String fieldDesc) {
        if(cr == null) {
            try {
                cr = new ClassReader(clazz.getCanonicalName());
            } catch (IOException e) {
                e.printStackTrace();
            }
            cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
        }
        if(ca == null) {
            ca = new AddFieldAdapter(cw, Opcodes.ACC_PUBLIC, fieldName, fieldDesc);
        } else {
            ca = new AddFieldAdapter(ca, Opcodes.ACC_PUBLIC, fieldName, fieldDesc);
        }
    }

    /**
     * 将字节码写入类的 .class 文件
     *
     */
    public void writeByteCode() {
        cr.accept(ca, ClassReader.SKIP_DEBUG);
        byte[] bys = cw.toByteArray();
        OutputStream os = null;
        try {
            os = new FileOutputStream(getFile());
            os.write(bys);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获得类文件的 File 对象
     * @return
     */
    private File getFile() {
        if(classFile == null) {
            StringBuffer sb = new StringBuffer();
            sb.append(clazz.getResource("/"))
                .append(clazz.getCanonicalName().replace(".", File.separator))
                .append(CLASS_FILE_SUFFIX);
            classFile = new File(sb.substring(6));
        }
        return classFile;
    }
} 

 4,字节码处理:PreCompileProcess.java

public class PreCompileProcess {

    public static void main(String[] args) {

        // 为 Student 添加字段
        AddField add = new AddField(Student.class);

        // 添加一个名为 address,类型为 java.lang.String 的 public 字段
        add.addPublicField("address", "Ljava/lang/String;");

        // 再增加一个名为 tel,类型为 int 的 public 方法
        add.addPublicField("tel", "I");

        // 重新生成 .class 文件
        add.writeByteCode();
    }
} 

 5,测试类:Test.java

public class Test {

    public static void main(String[] args) {
        Student stu = new Student();
        stu.setAge(10);
        stu.setName("Tom");
        stu.address = "Beijing";    // 新增加的 address 字段
        stu.tel = 56;               // 新增加的 tel 字段
        System.out.println("Name:    " + stu.getName());
        System.out.println("Age:     " + stu.getAge());
        System.out.println("Address: " + stu.address);
        System.out.println("Tel:     " + stu.tel);
    }
} 

 上面的代码需要 ASM 工具才能进行编译,ASM 可以到 http://asm.objectweb.org/ 上面去下载。

执行顺序:

javac Student.java
javac -cp .;lib/asm-all-3.1.jar PreCompileProcess.java
java -cp .;lib/asm-all-3.1.jar PreCompileProcess
javac Test.java
java Test

在 Student.java 没有修改的情况下,PreCompileProcess 只需要执行一次就可以了。

分享到:
评论

相关推荐

    ASM demo演示

    在“ASM demo演示”中,我们可以学习到以下几个关键知识点: 1. **ASM的基本概念**:ASM是一个集成了文件系统和卷管理器的功能,它可以自动管理磁盘空间,包括创建、扩展和缩小磁盘组,以及自动故障恢复。ASM通过...

    win32asm例子

    在【win32asm例子】中,我们可以学习到如何使用汇编语言调用Windows API。例如,创建窗口、响应消息、处理输入等。这涉及到以下几个关键概念: 1. **WinAPI调用**:通过`invoke`或`call`指令,汇编程序员可以调用...

    ASM_Demo.zip

    ASM_Demo.zip是一个包含ASM(Abstract Syntax Trees,抽象语法树)示例的压缩包,用于演示如何使用ASM库在Java字节码层面上进行操作。ASM是一个强大的Java字节码操控和分析框架,广泛用于动态代理、代码生成以及字节...

    asmck demo

    asmack的demo,功能可以参看下http://blog.csdn.net/yueqinglkong/article/details/37810865。

    ASM-demo.zip

    在给定的 "ASM-demo.zip" 压缩包中,我们可以预期找到一个基于 ASM 6.0 版本的演示项目,展示了如何生成一个 `.class` 文件并修改其中的方法。 首先,ASM 提供了两种主要的 API:树API(Tree API)和访问者API...

    asm + cglib demo

    在"asm + cglib demo"中,你可能会看到以下示例代码: 1. **ASM 示例**: 使用ASM创建一个新的类,或者修改已有的类,例如添加新的字段、方法,或者在已有方法中插入额外的逻辑。 2. **CGlib 示例**: 创建一个代理...

    ASM算法使用demo

    在提供的"ASM算法使用demo"中,你可能会找到以下内容: - 关于如何准备训练数据的指导,包括图像的选择和关键点的标注。 - PCA的详细解释和在形状模型中的应用。 - ASM和AAM算法的实现代码,可能包括Python或MATLAB...

    ASM4.2 DEMO

    在ASM 4.2这个DEMO中,我们将深入探讨ASM的核心概念、功能以及如何利用它来实现动态编程。 首先,ASM的核心是它的类访问器和类适应器机制。类访问器允许开发者读取类和方法的信息,而类适应器则可以用来插入、修改...

    stm32duino/ASM330LHH

    在STM32Duino平台上实现ASM330LHH的demo,意味着开发人员可以快速集成和测试ASM330LHH传感器的功能,如读取加速度和陀螺仪数据,进行姿态解算等。这通常涉及以下几个关键知识点: 1. **STM32硬件接口**:ASM32LHH...

    asm5.0 源码+demo+doc

    ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class ...

    demo2.asm

    demo2.asm

    x86_asm_demo.zip

    x86_asm_demo.zip这个压缩包文件包含了一个x86架构汇编语言的演示示例,旨在帮助学习者掌握汇编语言的基本用法和优化技巧。通过分析和实践这个demo,你可以了解以下关键知识点: 1. **基本指令**:x86汇编包括数据...

    asm4.1 jar+demo+doc

    ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class ...

    ASM算法实现对齐功能代码

    ASM算法实现对齐功能代码 经典算法asm,内部对齐部分代码,就是求解那个矩阵代码

    ASM操作字节码,动态生成Java类class文件

    ASM是一个开源的Java字节码操控和分析框架,它能够用来动态生成类或者增强已有类的功能。ASM可以被用来创建Java代理、实现元编程、甚至深入到Java虚拟机(JVM)层面进行性能优化。在Java开发中,ASM库允许我们直接...

    stc8_demo程序.rar_DEMO_STC8 PCA_stc8_stc8 pwm_stc8a8

    stc8,DEMO程序: uart stc8aid delay IO timer adc pwm pca

    asm算法 opencv实现

    压缩包中的"asmlib-demo"可能是实现ASM算法的一个示例库或代码项目。这个库可能包含用于读取图像、处理图像、检测特征点、执行形状建模和迭代优化的函数。通过分析和运行这个示例代码,开发者可以更好地理解和掌握...

    演示Asm字节码插桩asmd-demo-master.zip

    在本案例"asmd-demo-master.zip"中,我们将探讨Asm库在字节码插桩中的应用。 Asm是一个开源的Java字节码操控和分析框架,它可以用来动态生成类或者分析运行中的Java程序。Asm提供了非常底层的API,可以直接操作字节...

    all_the_time.zip_DEMO_STM8S ASM

    在"all_the_time.zip_DEMO_STM8S_ASM"这个压缩包中,我们很显然面对的是一个关于STM8S微控制器的汇编语言示例项目,名为"All_the_time"。汇编语言是一种低级编程语言,程序员直接对处理器的指令集进行编程,从而实现...

    SpringBoot 简单Demo

    【SpringBoot 简单Demo】是一个基于SpringBoot框架的示例项目,旨在帮助初学者快速理解并掌握SpringBoot的核心特性和应用场景。SpringBoot是由Pivotal团队开发的一个开源框架,它简化了Java企业级应用的开发过程,...

Global site tag (gtag.js) - Google Analytics