- 浏览: 81338 次
- 性别:
- 来自: 上海
文章分类
最新评论
使用ASM来书写Java代码(转)
1. 流程控制:
a) 说明:JVM提供了基本的流程控制结构,这些结构都是基于Label而实现的。这些跳转指令,包括基于比较结果的有条件跳转和无条件的GOTO指令。另外,JVM也提供了实现switch结构的LOOKUPSWITCH和TABLESWITCH指令,其中LOOKUPSWITCH是基于键比较的,而TABLESWITCH则是基于键索引的,因此后者的匹配速度更快。
2. 接口声明:
ClassWriter cw = new ClassWriter(false);
cw.visit(V1_5, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, "asm/IA", null,
"java/lang/Object", null);
cw.visitSource("IA.java", null);
cw.visitEnd();
等价于:
public interface IA{}
3. 类声明:
a) 抽象类:
ClassWriter cw = new ClassWriter(false);
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER + ACC_ABSTRACT, "asm/A", null,
"java/lang/Object", null);
cw.visitSource("A.java", null);
等价于:
public abstract class A{}
b) 具体类:
ClassWriter cw = new ClassWriter(false);
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, "asm/A", null, "java/lang/Object", null);
cw.visitSource("A.java", null);
cw.visitEnd();
等价于:
public class A{}
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;",
ull, 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编译器来生成枚举。
相关推荐
JavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-attrsJavaEE源代码 asm-...
JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2...
文档描述了在ASM算法在JAVA和MATLAB上的实现,并且有代码。
就是 Asm汇编语言转易语言的置入代码的工具 此工具有双引擎 ------ Masm引擎 跟 OD引擎 Masm引擎兼较好 OD引擎兼容性(我都不想吐槽) 汇编功能支持 代码高亮 (亮瞎我的狗眼啊..魂淡) 此版本为Ver1.0 如果可能的...
学习asm汇编的代码
ASM提供了一些常见的字节码转换和分析算法,可以从中构建自定义复杂转换和代码分析工具。ASM提供与其他Java字节码框架类似的功能,但专注于 性能。因为它的设计和实现尽可能小而且快,所以它非常适合在动态系统中...
ASM操作字节码,动态生成Java类class文件,模拟Spring的AOP实现原理。
ASM算法,包含有68个特征点的人脸检测,其中提供75个特征点的model。有参考网站。
该软件能对MCS51单片机 编辑后产生的HEX文件进步反编辑产生ASM文件用代码研究
java asm jar包,包含doc已经pom,自己从官网下载的,无删减。
ASM 帮助文档(java字节码操作) 对字节码进行操作的jar包。
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
c32asm 代码编辑程序更改标题图标c32asm 代码编辑程序更改标题图标c32asm 代码编辑程序更改标题图标c32asm 代码编辑程序更改标题图标c32asm 代码编辑程序更改标题图标c32asm 代码编辑程序更改标题图标c32asm 代码...
MIXIN是使用ASM的Java的特性/混合框架
Asm转com不支持伪指令。只是作为学习16位汇编的小工具。
使用asm压缩音频 VC++代码编写 msdn上的代码
oracle不使用oracleasm的包配置ASM磁盘配置方法
Java的asm文档,来自官方。asm4-guide.pdf。ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。...
红外遥控解码 ASM 程序 源代码,很经典的拿去改改就可以直接使用了
在 Visual C++ 中使用内联汇编 VC内联ASM汇编 混合使用C和汇编代码的程序(用__asm写c函数)