`

使用ASM为一个类增加属性

阅读更多

使用ASM可以方便的访问和修改一个类,或者在JVM载入前动态更新一个类也是可以的,如下,

为一个类动态增加一个属性,类Student如下:

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;
	}
}

 使用ASM实现一个类写入属性AddFieldAdapter,如下:

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();
    }
} 

 实现一个类AddField调用上面的类去添加属性,如下:

public class AddField {
	private Class<?> clazz;
    private ClassReader cr;
    private ClassWriter cw;
    private ClassAdapter ca;
    private File classFile;

    private final static String CLASS_FILE_SUFFIX = ".class";

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

    public void addPublicField(String fieldName, String fieldDesc) {
        if(cr == null) {
            try {
            	// com.demo2.Student
                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);
        }
    }

    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();
            }
        }
    }

    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;
    } 
    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();
    }
}

 使用反编译工具查看生成的CLASS文件,即可看到动态添加的属性了。

 

 

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    ASM维护使用指导手册

    本手册的目的是为IT专业人员提供ASM的维护和使用指南,帮助他们更好地理解和操作ASM实例,确保数据库系统的稳定运行。 2. **范围** 本手册适用于那些需要管理Oracle数据库环境中ASM实例的系统管理员和DBAs。内容...

    asm-attrs-2.1.jar.zip

    标题中的"asm-attrs-2.1.jar.zip"是一个压缩包文件,其主要包含的是一个名为"asm-attrs-2.1.jar"的Java可执行jar文件和一个"asm-2.2.1.jar.license.txt"的文本文件。这个jar文件很可能是ASM库的一个特定版本,ASM是...

    ASM官方文档

    ASM官方文档不仅为数据库管理员提供了一个关于ASM使用的全面指南,同时也从技术细节和管理实践角度,为数据库的存储优化和管理提供了理论和实践的参考。这些内容对于任何需要深入了解并实施Oracle ASM解决方案的专业...

    asm-attrs.jar.zip

    ASM-Attrs.jar 是ASM库的一个扩展,它专注于处理和解析类的属性信息,提供了一种高效且灵活的方式来访问和修改这些属性。 ASM库的核心功能主要包括以下几点: 1. **字节码生成**:ASM能够动态地创建类和接口,并将...

    asm-attrs-1.5.3.jar.zip

    总之,ASM-attrs-1.5.3.jar作为ASM库的一个版本,为Java开发者提供了强大的字节码操作能力,特别是对于处理类属性方面,使得我们可以创建更复杂、更灵活的程序。同时,了解和遵循相关的许可协议,是使用开源库的基本...

    asm-3.1.jar

    3. **字节码修改**:在解析类文件后,ASM允许开发者修改这些对象模型,比如添加、删除或修改方法体、字段和类属性。这种能力对于AOP(面向切面编程)和代码增强等场景非常有用。 4. **字节码生成器**:ASM提供了...

    asm官方代码文档

    《ASM官方代码文档》是关于ASM汇编语言框架的重要参考资料,ASM是一个Java字节码操纵和分析框架,常用于动态代理、代码混淆、性能监控等领域。ASM库允许开发者以低级别的方式与Java字节码交互,这对于理解底层操作...

    ASM操作加盘.7z

    1. **ASM磁盘组**:ASM磁盘组是ASM中逻辑存储的单位,它由一个或多个物理磁盘组成,提供冗余和数据分布策略。磁盘组有多个类型,如正常型(NORMAL)、高冗余型(HIGH)和外部冗余型(EXTERNAL),分别对应不同的数据...

    C++汇编x64调用asm文件例子

    假设你有一个名为`asm_func.asm`的汇编文件,它包含以下代码: ```asm ; asm_func.asm section .text global asm_func asm_func: ; 汇编代码实现 mov rax, rcx add rax, rdx ret ``` 这个简单的汇编函数接受...

    asm-tree-3.3.1.jar.zip

    ASM Tree库则是ASM框架中的一个模块,它的主要作用是将ASM低级别的字节码操作转化为直观的树形结构,便于开发者理解和处理。在ASM Tree 3.3.1版本中,开发者可以更方便地对Java类的结构进行解析和修改,提供了更高...

    asm-attrs-2.0.jar.zip

    标题中的"asm-attrs-2.0.jar.zip"是一个压缩文件,它包含了ASM库的一个特定版本,即ASM Attributes模块的2.0版本。ASM是一个Java字节码操控和分析框架,广泛用于动态代理、代码分析和转换等场景。ASM库主要用于生成...

    asm-tree-2.1.jar.zip

    ASM是一个Java字节码操控和分析框架,它可以直接解析和生成Java类文件,而ASM Tree库则是ASM框架的一部分,它提供了将字节码转换为抽象语法树(AST)的能力,进而便于进行代码分析和修改。本文将详细介绍ASM Tree ...

    asm-all-3.3.1-sources.jar.zip

    标题中的"asm-all-3.3.1-sources.jar.zip"是一个包含ASM库源代码的压缩文件,版本为3.3.1。ASM是一个Java字节码操控和分析框架,常用于动态代理、代码分析、代码生成等场景。ASM库主要用于在运行时解析和生成Java类...

    如何使用Visual_Studio编程调试ASM汇编语言程序_masm_9

    ### 如何使用Visual Studio 编程调试ASM汇编语言程序_masm_9 #### 重要知识点解析 在本文中,我们将详细介绍如何使用 Visual Studio IDE 环境来编写、调试和运行 ASM 汇编语言程序(特别是 masm9)。这不仅适用于...

    centos6 asm依赖包

    在Oracle ASM(Automatic Storage Management)的环境中,CentOS 6是一个常见的操作系统选择,因为它提供了稳定性和兼容性。Oracle ASM是一种集成的存储管理解决方案,专为Oracle数据库设计,它简化了存储管理和提供...

    ORACLE 10g所需asm包

    Oracle 10g的Automatic Storage Management (ASM) 是Oracle数据库管理系统中的一个重要组件,它提供了一种集成的、自动化的存储管理解决方案。在Red Hat 4操作系统环境下安装Oracle 10g ASM时,需要一些特定的包来...

    Oracle 10.2 ASM 最佳实践 最终版本

    - **概念**:XML ASM虚拟文件夹提供了一个基于XML的接口来访问ASM中的文件。 - **优点**:可以简化文件的查找和管理工作,并支持通过FTP等方式访问虚拟文件夹。 #### 模板 - **使用模板**:通过预定义的模板可以...

    logback日志级别动态切换的终极方案(Java ASM使用).doc

    ASM是一个Java字节码操控和分析框架,可以用来动态修改类的字节码。通过ASM,可以在程序运行时修改Logger类的字节码,插入自定义的逻辑,如设置日志级别或过滤特定日志。这种方法需要对ASM、Java Agent和JVM指令有...

    oracle ASM添加磁盘

    - **创建 ASM 磁盘**: 在第一个节点上使用 Oracle ASM 的脚本或命令行工具创建磁盘实例,例如:`/etc/init.d/oracleasm createdisk VOLDISK7 /dev/sddlmax1`。 - **查看 ASM 磁盘列表**: 使用 `listdisks` 命令查看...

    vs2008搭建asm模板

    总结来说,使用VS2008搭建ASM模板的过程包括:创建空的Win32控制台应用项目,添加汇编源代码文件,设置文件类型为汇编,编写汇编代码,最后编译和调试。通过这种方式,我们可以充分利用VS2008的强大功能,高效地进行...

Global site tag (gtag.js) - Google Analytics