asm学习(4)--Tree API(2007-05-31 14:09:10)
asm文档阅读已快到尾声,最后一章已到Tree API的使用,Tree
API就是针对Class,Method,Field等其它同级的属性进行了一个类包装,可以让我们用面向对像的形式来操作字节码,但也不要负于太高的期望,要操作字节码还真得弄懂了才能下手,Tree
API带给我们的只是代码量的减少。Tree
API是通过实现ClassVisitor接口而实现的,从另外一个角度来说就是给我们又封装了一层ClassVisitor,让我们开发便利点。
同样,我们可以用它来实现AOP。
ClassWriter cw = new
ClassWriter(0);
ClassNode classNode = new ClassNode();
classNode.fields.add(new FieldNode(ACC_PUBLIC,
"count", "I", null,
new
Integer(0)));
ClassReader cr = new
ClassReader("com.c2.asm.B");
//注意classReader.accept的位置,必须为在填充了Node信息之前,如之后就得不到本来类中的信息。
cr.accept(classNode, 0);
List methods = classNode.methods;
for (MethodNode mn : (List<MethodNode>)
methods) {
InsnList insns =
mn.instructions;
Iterator j =
insns.iterator();
while (j.hasNext()) {
AbstractInsnNode in = (AbstractInsnNode) j.next();
int op =
in.getOpcode();
//捕捉到结尾处
if ((op
>= IRETURN && op <= RETURN) || op == ATHROW) {
InsnList il = new InsnList();
il.add(new InsnNode(ICONST_3));
il.add(new VarInsnNode(ISTORE,3));
//在这里可以控制在什么地方插入新代码
insns.insert(in.getPrevious(),il);
}
}
InsnList il = new
InsnList();
il.add(new
InsnNode(ICONST_4));
il.add(new
VarInsnNode(ISTORE,4));
insns.insert(il);
//同样,Stack和Locals瞎写的,猜得差不多吧
mn.maxStack += 3;
mn.maxLocals += 4;
}
//注意classNode.accept的位置,必须为在填充了Node信息之后
classNode.accept(cw);
加载中,请稍候...