您的位置:首页 > 移动开发 > Objective-C

字节码操作(ObjectWeb ASM)

2010-11-26 09:12 190 查看
介绍

  ObjectWeb ASM轻量级的Java字节码处理框架。它可以动态生成二进制格式的stub类或其他代理类,或者在类被JAVA虚拟机装入内存之前,动态修改类。ASM 提供了与 BCEL和SERP相似的功能,只有22K的大小,比起350K的BCEL和150K的SERP来说,是相当小巧的,并且它有更高的执行效率,是BCEL的7倍,SERP的11倍以上。

  项目主页:http://asm.objectweb.org/

示例代码

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class TestAsm implements Opcodes{
public static void main(String[] args) throws Exception{
ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_MAXS);//这样设置才能自动计算
String className="Example";
cw.visit(V1_5,ACC_PUBLIC,className,null,"java/lang/Object",new String[]{"java/lang/Cloneable",ITest.class.getName().replace('.','/')});

String field="test";
Object defaultValue=123d;
String setMd="setTest";
String getMd="getTest";
cw.visitField(ACC_PRIVATE,field,"D",null,null).visitEnd();

MethodVisitor mv=cw.visitMethod(ACC_PUBLIC,getMd,"()D",null,null);
mv.visitCode();
mv.visitVarInsn(ALOAD,0);
mv.visitFieldInsn(GETFIELD,className,field,"D");
mv.visitInsn(DRETURN);
mv.visitMaxs(0,0);// 自动计算局部变量和栈大小
mv.visitEnd();
cw.visitEnd();

mv=cw.visitMethod(ACC_PUBLIC,setMd,"(D)V",null,null);
mv.visitCode();
mv.visitVarInsn(ALOAD,0);
mv.visitVarInsn(DLOAD,1);
mv.visitFieldInsn(PUTFIELD,className,field,"D");
mv.visitInsn(RETURN);
mv.visitMaxs(0,0);// 自动计算
mv.visitEnd();

// 下面产生构造方法
mv=cw.visitMethod(ACC_PUBLIC,"<init>","()V",null,null);
mv.visitCode();
mv.visitVarInsn(ALOAD,0);
mv.visitMethodInsn(INVOKESPECIAL,"java/lang/Object","<init>","()V");
if(defaultValue != null){
//在构造方法中赋默认值
mv.visitVarInsn(ALOAD,0);
mv.visitLdcInsn(Double.parseDouble(defaultValue.toString()));
mv.visitFieldInsn(PUTFIELD,className,field,"D");
}
mv.visitInsn(RETURN);
mv.visitMaxs(0,0);// 自动计算
mv.visitEnd();

cw.visitEnd();

byte[] bs=cw.toByteArray();
// FileUtil.writeFile("d:/test/asm/Example.class",bs);

MyCLassLoader loader=new MyCLassLoader();
Class c=loader.defineClass(bs);

c.getConstructor(new Class[0]);
ITest ins=(ITest)c.newInstance();
//ins.setTest(100.0d);
System.out.println(ins.getTest());
}

public interface ITest{
public double getTest();

public void setTest(double d);
}

public static class MyCLassLoader extends ClassLoader{
public Class defineClass(byte[] data){
return super.defineClass(null,data,0,data.length,null);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐