`
alvinqq
  • 浏览: 185394 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

asm操作java(三)

    博客分类:
  • java
阅读更多
1.Signature:
a)说明:J2SE 5.0为了支持范型,参数化参数,Annotation和枚举等新增特性,因此增加了一个Signature属性,作为类,字段,方法的Description之外的一个辅助机制。

2. Annotation:
a) Annotation:
i.定义:
cw.visit(V1_5, ACC_PUBLIC + ACC_ANNOTATION + ACC_ABSTRACT + ACC_INTERFACE, 
"asm/AN", null, "java/lang/Object", new String[] 
{ "java/lang/annotation/Annotation" });


等价于:
public @interface AN {}


ii.使用:通过ClassVisitor,FieldVisitor,MethodVisitor上的visitAnnotation()方法,来获取一个AnnotationVisitor实例,从而为类,字段,方法设置Annotation。
AnnotationVisitor av0 = cw.visitAnnotation("Lasm/AN;", false);
av0.visitEnd();

@AN
public class A{}


b)属性:
i.定义:
mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "age", "()I", null, null);
mv.visitEnd();

mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "name", "()Ljava/lang/String;", 
null, null);
av0 = mv.visitAnnotationDefault();
av0.visit(null, "A");
av0.visitEnd();
mv.visitEnd();


等价于:
public @interface AN {
     int age();
     String name() default "A";
}


ii.使用:
av0 = cw.visitAnnotation("Lasm/AN;", false);
av0.visit("age", new Integer(1));
av0.visit("name", "B");
av0.visitEnd();

等价于:
@AN(age = 1, name = "B")
public class A {
}

3.范型:
a)定义:
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, "asm/A", "<T::Lasm/IA;G:Lasm/B;>Ljava/lang/Object;Ljava/lang/Comparable;", "java/lang/Object", new String[] { "java/lang/Comparable" });


等价于:
public class A<T extends IA, G extends B> implements Comparable {
…
}


说明:在类定义当中使用范型时,需要增加Signature字段来添加范型信息。该Signature的组成是“<范型参数名:范型扩展的类:范型扩展的接口…>父类描述 接口描述”

b)范型字段:
i.定义:
FieldVisitor fv = cw.visitField(ACC_PRIVATE, "l", "Ljava/util/List;", 
"Ljava/util/List<Ljava/lang/String;>;", null);
fv.visitEnd();


等价于:
private List<String> l;


说明:在声明范型字段时,需要增加Signature来增加范型信息。该Signature的组成是
“基类型描述<参数类型描述>”

ii.使用:由于范型信息只是供编译器在编译时进行类型检查,而在编译以后该信息将会被擦除,因此在使用时与没有范型的情况一致。

c)范型方法:
i.定义:
mv = cw.visitMethod(ACC_PUBLIC, "getList", "(Ljava/util/Map;)Ljava/util/List;", "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/Integer;>;)Ljava/util/List<Ljava/lang/String;>;", null);


等价于:
public List<String> getList(Map<String, Integer> maps) {…}


ii.使用:由于范型信息只是供编译器在编译时进行类型检查,而在编译以后该信息将会被擦除,因此在使用时与没有范型的情况一致。

4.枚举:
a)定义:
ClassWriter cw = new ClassWriter(false);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;

cw.visit(V1_5, ACC_PUBLIC + ACC_FINAL + ACC_SUPER + ACC_ENUM, "asm/E", 
"Ljava/lang/Enum<Lasm/E;>;", "java/lang/Enum", null);
cw.visitSource("E.java", null);

fv = cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC + ACC_ENUM, "E1", "Lasm/E;", null, null);
fv.visitEnd();         //   定义静态字段E1

fv = cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC + ACC_ENUM, "E2", "Lasm/E;", null, null);
fv.visitEnd();         //   定义静态字段E2

fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC + ACC_SYNTHETIC, "ENUM$VALUES", 
"[Lasm/E;", null, null);
fv.visitEnd();         //   定义存储所有枚举值的静态字段ENUM$VALUES

mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();

//   初始化E1
mv.visitTypeInsn(NEW, "asm/E");
mv.visitInsn(DUP);
mv.visitLdcInsn("E1");
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKESPECIAL, "asm/E", "<init>", "(Ljava/lang/String;I)V");
mv.visitFieldInsn(PUTSTATIC, "asm/E", "E1", "Lasm/E;");

//   初始化E2
mv.visitTypeInsn(NEW, "asm/E");
mv.visitInsn(DUP);
mv.visitLdcInsn("E2");
mv.visitInsn(ICONST_1);
mv.visitMethodInsn(INVOKESPECIAL, "asm/E", "<init>", "(Ljava/lang/String;I)V");
mv.visitFieldInsn(PUTSTATIC, "asm/E", "E2", "Lasm/E;");

//   初始化ENUM$VALUES,将E1,E2存入ENUM$VALUES当中
mv.visitInsn(ICONST_2);
mv.visitTypeInsn(ANEWARRAY, "asm/E");
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitFieldInsn(GETSTATIC, "asm/E", "E1", "Lasm/E;");
mv.visitInsn(AASTORE);
mv.visitInsn(DUP);
mv.visitInsn(ICONST_1);
mv.visitFieldInsn(GETSTATIC, "asm/E", "E2", "Lasm/E;");
mv.visitInsn(AASTORE);
mv.visitFieldInsn(PUTSTATIC, "asm/E", "ENUM$VALUES", "[Lasm/E;");
mv.visitInsn(RETURN);
mv.visitMaxs(8, 0);
mv.visitEnd();

mv = cw.visitMethod(ACC_PRIVATE, "<init>", "(Ljava/lang/String;I)V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ILOAD, 2);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Enum", "<init>", (Ljava/lang/String;I)V");
mv.visitInsn(RETURN);
mv.visitMaxs(3, 3);
mv.visitEnd();

//   使用arraycopy()方法,将ENUM$VALUES的值存入一个新数组当中,并返回。
mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "values", "()[Lasm/E;", null, null);
..
mv.visitEnd();

//   返回某个枚举值的字符表示
mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "valueOf", 
"(Ljava/lang/String;)Lasm/E;", null, null);
mv.visitEnd();
cw.visitEnd();


等价于:
public enum E {
     E1, E2

}
b)        使用:
mv.visitFieldInsn(GETSTATIC, "asm/E", "E1", "Lasm/E;");

等价于:
E e = E.E1;

c)        说明:从上面的代码可以看到,即使是一个简单的枚举,也需要使用很多的代码才能定义,因此更可行的办法是使用Java编译器来生成枚举。
分享到:
评论

相关推荐

    asm_java.rar_asm_java

    ASM库在Java中通常用于创建字节码级别的操作,例如代码分析、转换和生成,这在构建复杂系统如ASM股市模拟器时可能很有用。 总的来说,这个`asm_java.rar_asm_java`压缩包提供了一个完整的ASM模型的Java实现,包括了...

    asm操作指南(中文)

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

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

    在Java开发中,ASM库允许我们直接操作字节码,这对于理解和实践AOP(面向切面编程)的概念尤其有用,就像Spring框架中的AOP实现。 面向切面编程(AOP)是一种编程范式,它允许程序员定义“切面”,这些切面封装了...

    ASM 帮助文档(java字节码操作)

    ASM 帮助文档(java字节码操作) 对字节码进行操作的jar包。

    ASM Java字节码操作框架

    ASM Java字节码操作框架PPT,结合已有AOP实现方法,对比所有对Java字节码操作方法做比较

    Java字节码和asm入门资料

    ASM是一个开源的Java字节码操控和分析框架,它可以直接用来生成和修改Java类文件,是Java动态代理和字节码增强技术的重要工具。在深入学习Java字节码和ASM之前,我们需要先理解Java编译和运行的基本过程。 1. **...

    Mixin,MIXIN是使用ASM的Java的特性/混合框架.zip

    通过ASM,Mixin能够精确地定位并修改Java类的字节码,实现对目标类的精细操作。 Mixin框架的设计理念是基于面向切面编程(AOP)思想,但与传统的AOP实现不同,如Spring AOP,Mixin不使用代理模式。它直接将混入...

    cglib和asm

    ASM提供了一套直接操作Java字节码的底层API,允许开发者在运行时对类进行深度定制。ASM的强大之处在于其灵活性,但同时也要求使用者对Java虚拟机的内部结构有较深入的理解。ASM通常被用于编译器、代码分析工具或动态...

    ASM4手册中文版.pdf.zip

    ASM4是中国Java开发者常用的一款字节码操作框架ASM的第四个主要版本,它主要用于动态生成和分析Java字节码。ASM是一个低级别的库,可以直接操作和生成类的字节码,这在创建编译器、代码分析工具以及运行时代码修改等...

    asm 最新包三个 包括3.0 3.1 3.2

    ASM的灵活性和高性能使得它成为Java字节码操作的首选工具之一。 总而言之,ASM-3.0、3.1和3.2这三个版本展示了ASM框架在不同时间点的发展和改进,它们分别代表了ASM在不同阶段的功能和性能水平。对于需要使用ASM...

    asm_java人工股市.zip_股市

    1. ASM框架:ASM是一个开源库,它允许对Java字节码进行低级别的操作,如生成、修改和分析。ASM的核心是ClassWriter和ClassReader类,它们分别用于创建新的字节码和解析现有的字节码。在人工股市项目中,ASM可能被...

    ASM使用指南-中文版

    4. **Opcode**:Java字节码的操作码,ASM库提供了对应的常量,使得开发者可以直接引用它们来构造字节码序列。 5. **字段和方法的访问和修改**:ASM允许开发者添加、删除或修改类的字段和方法,包括其访问权限、类型...

    基于ASM的Java作业辅助批阅工具的实现.zip

    ASM提供了一组API,允许开发者直接操作字节码,这对于理解类的内部结构、进行动态代理、代码混淆、性能分析等任务非常有用。 二、ASM在作业批阅工具中的应用 在Java作业辅助批阅工具中,ASM主要负责以下任务: 1....

    基于ASM的Java作业辅助批阅工具的实现.pdf

    1. **代码自动修改**:通过ASM,工具可以直接操作Java字节码,对类文件进行无侵入式的修改,以适应批阅需求。 2. **关键类库使用分析**:监控和记录学生代码中对重要API的使用,提供详细的使用报告。 3. **调用频率...

    asm-2.2.3.jar,asm-commons-2.2.3.jar,asm-util-2.2.3.jar

    ASM是一个强大的Java字节码操控和分析...asm-2.2.3.jar、asm-commons-2.2.3.jar和asm-util-2.2.3.jar这三部分构成了ASM 2.2.3版本的主要组件,分别提供了核心功能、常用工具和辅助类,以满足不同层次的字节码操作需求。

    Java ASM,learn-java-asm-main.zip

    Java ASM 是一个强大的字节码操控和分析框架,它允许你在运行时动态生成类和接口,或者修改已存在的类。ASM 提供了低级别的访问,让你可以深入到 Java 类的内部结构,这对于创建代码生成器、编译器、性能监视工具等...

    asm4开发手册-英文原版

    描述中提到的cglib库动态代理底层采用ASM作为其字节码操作的工具,这说明cglib在实现Java中的动态代理时,依赖于ASM库来操作Java类的字节码。动态代理是指在运行时创建一个实现了目标接口的代理实例,代理实例会将...

    java asm 3.3.1

    1. **字节码操作**:ASM提供了一种低级别的接口,允许程序员直接操作Java字节码。它将类文件解析为一棵抽象语法树(AST),用户可以通过遍历和修改这棵树来生成或修改字节码。 2. **类访问器和方法访问器**:ASM...

    ASM字节码操作简单实例

    ASM字节码库是Java字节码操作的强大工具,它允许程序员在运行时动态生成类或者增强已有类的功能。在本实例中,我们将探讨如何利用ASM实现简单的面向切面编程(AOP)功能,这是一种在不修改源代码的情况下,添加额外...

    java-asm:java asm原始解析

    总之,Java ASM提供了一种底层的方式来操作Java字节码,它强大而灵活,但使用起来也需要一定的学习成本。在理解和掌握了ASM的基本原理和API后,我们可以构建出功能强大的工具和框架,以满足各种高级编程需求。

Global site tag (gtag.js) - Google Analytics