`

使用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开发者提供了强大的字节码操作能力,特别是对于处理类属性方面,使得我们可以创建更复杂、更灵活的程序。同时,了解和遵循相关的许可协议,是使用开源库的基本...

    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-3.1.jar

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

    asm官方代码文档

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

    ASM操作加盘.7z

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

    asm-attrs-2.0.jar.zip

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

    asm-tree-3.3.1.jar.zip

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

    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类...

    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