`

ASM

    博客分类:
  • j2se
阅读更多


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

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

Java codepublic 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

Java codeimport 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

Java codeimport 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

Java codepublic 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

Java codepublic 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 只需要执行一次就可以了。
分享到:
评论
1 楼 Tristan_S 2013-10-29  
这个有点意思

相关推荐

    asm.jar各个版本

    asm-1.3.3.jar, asm-1.3.4.jar, asm-1.3.5.jar, asm-1.4.1.jar, asm-1.4.2.jar, asm-1.4.3.jar, asm-1.4.jar, asm-1.5.1.jar, asm-1.5.2.jar, asm-1.5.3.jar, asm-2.0.jar, asm-2.1.jar, asm-2.2.1-sources.jar, asm...

    1、ASM1064 DATASHEET; 2、ASM1064 参考原理图设计; 3、支持的SPI Flash清单

    ASM1064是一款高性能的PCI Express to SATA 3.0桥接芯片,由ASMIC公司设计制造。这款芯片主要用于实现PCI Express接口与SATA接口之间的数据高速传输,广泛应用于存储扩展卡、固态硬盘控制器等领域。以下是关于ASM...

    ASM 1351.zip

    ASM 1351 是一款由ASMedia( ASM 微电子)公司开发的集成电路,主要应用于数据传输和接口控制领域。这个压缩包“ASM 1351.zip”包含了与ASM 1351相关的三个关键文件:一个固件升级工具、数据表以及设计套件。 1. **...

    redhat/centos6.9 kmod-oracleasm/oracleasm-support/oracleasm rpm包

    kmod-oracleasm-2.0.8-15.el6_9.x86_64 oracleasm-support-2.1.8-1.el6.x86_64 oracleasmlib-2.0.4-1.el6.x86_64 安装顺序: rpm -ivh kmod-oracleasm-2.0.8-15.el6_9.x86_64.rpm rpm -ivh oracleasm-support-2.1.8...

    cglib-2.2.jar asm-tree.jar asm-commons.jar asm.jar

    【标题】"cglib-2.2.jar asm-tree.jar asm-commons.jar asm.jar" 提供的是一组用于Java编程的库,它们主要用于实现动态代理和字节码操作。 【描述】"cglib动态代理模式jar包 cglib-2.2.jar asm-tree.jar asm-...

    EditPlus(附asm.acp,asm.stx)

    ASM文件的扩展名通常为`.asm`,它允许程序员对计算机硬件进行精确控制,尽管相比高级语言,学习曲线较为陡峭,但在某些特定场景,如系统编程或优化代码时,汇编语言显得尤为重要。 【asm.acp】和【asm.stx】是...

    asm 6.0 工具集

    这套工具包括了ASM、ASM-Util、ASM-TREE和ASM-ANALYSIS等组件,每个都有其特定的功能和用途。 **ASM库**是核心部分,提供低级别的API来生成和解析Java字节码。ASM库允许开发者直接操作字节码,创建和修改类,甚至在...

    asm-util.jar

    asm-util-1.3.4.jar, asm-util-1.3.5.jar, asm-util-1.4.1.jar, asm-util-1.4.3.jar, asm-util-1.5.1.jar, asm-util-1.5.2.jar, asm-util-1.5.3.jar, asm-util-2.0.jar, asm-util-2.1.jar, asm-util-2.2.1-sources....

    各种oracleasm rpm包(Linux下配置ASM使用)

    包含如下oracleasm包: kmod-oracleasm-2.0.6.rh1-3.el6.x86_64.rpm oracleasm-2.0.8-4.el6_6.src.rpm oracleasm-2.0.8-6.el6_7.src.rpm oracleasm-2.0.8-8.el7.src.rpm oracleasm-2.0.8-15.el7.centos.src.rpm ...

    asm操作指南(中文)

    ### asm操作指南(中文)知识点总结 #### 一、ASM框架简介 - **定义与功能**:ASM是一个Java字节码操纵框架,主要用于动态生成类或增强现有类的功能。通过直接生成二进制`.class`文件,ASM能够在类被加载到Java...

    ASM1061.zip

    ASM1061是一款由ASMtek(Asmedia Technology Inc.)公司生产的高性能PCI Express (PCIe) to Serial Advanced Technology Attachment (SATA)桥接芯片,主要用于扩展计算机系统的SATA接口,使得硬件开发人员能够轻松地...

    FIDO UAF ASM 接口文档

    ### FIDO UAF框架中ASM API详解 #### 1. 概述 FIDO (Fast IDentity Online) 是一种开放协议,旨在减少对密码的依赖并提供更安全的身份验证方式。UAF (Universal Authentication Framework) 是FIDO联盟推出的一个...

    stm32duino/ASM330LHH

    在本案例中,我们关注的是ASM330LHH,这是一款高性能的三轴加速度计和三轴陀螺仪传感器,由意法半导体(STMicroelectronics)制造。ASM330LHH广泛应用于运动检测、航姿参考系统、手势识别以及物联网设备中的动态平衡...

    ASM1083 PCIe转PCI芯片数据表

    ASM1083 PCIe转PCI芯片数据表 ASM1083 PCIe转PCI芯片数据表是ASMedia TECHNOLOGY INC.公司出品的一款PCIe转PCI桥接芯片,其主要功能是将PCI Express(Peripheral Component Interconnect Express)接口转换为传统的...

    C-include-ASM.zip_asm中include asm_c语言中嵌套asm

    在标题提到的"C-include-ASM.zip_asm中include_asm_c语言中嵌套asm",我们主要讨论的是如何在C程序中使用汇编代码,并且可能涉及到如何在汇编代码中包含其他汇编模块。 首先,让我们了解一下C语言嵌套汇编的基本...

    asm 最新版手册

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

    汇编插件 asm-dude, 支持 Visual Studio 2022

    **汇编插件 AsmDude 用于 Visual Studio 2022** AsmDude 是一款专为Visual Studio 2022设计的汇编语言插件,它极大地提升了开发人员在使用汇编语言时的工作效率和代码质量。这款插件对新手极其友好,即使是编程经验...

    ASM1061资料文件.rar

    ASM1061是一款广泛应用在PCI-E到SATA转换中的控制器芯片,由ASMtek公司生产。这个"ASM1061资料文件.rar"压缩包包含了关于该芯片的详细设计资料,对于开发者、工程师或者硬件爱好者来说是极其宝贵的资源。下面我们将...

    oracle不使用oracleasm的包配置ASM磁盘配置方法

    ### Oracle 不使用 OracleASM 的包配置 ASM 磁盘配置方法 #### 概述 在 Oracle 数据库系统中,自动存储管理(ASM)是用于管理数据库文件的一种高性能、高可用性的解决方案。通常情况下,ASM 依赖于 Oracle 提供的 ...

    asm330lhh1_datasheet_gyroscope_asm330lhh精度_

    《ASM330LHH1陀螺仪:高精度数据手册解析》 ASM330LHH1是一款高性能的固态陀螺仪,主要用于需要精确测量角速度的应用中。这款陀螺仪以其卓越的精度和稳定性,广泛应用于无人机、机器人导航、虚拟现实设备以及各类...

Global site tag (gtag.js) - Google Analytics