【ASM的学习】asm官方手册学习心得01

【背景】


在正式学习asm时,大家需要对class字节码的格式,语法有一定了解。





根据手册上面的例子,然后生成一个类,再读取一个类进行:

package TestCase;

import org.objectweb.asm.*;

import java.io.*;

/**
 * Created with IntelliJ IDEA.
 * User: Administrator
 * Date: 13-8-6
 * Time: 上午10:01
 * To change this template use File | Settings | File Templates.
 */
public class testProxy
{
    public static void main(String[] args){
        try{
            File f_input=new File("d:/test.class") ;
            FileInputStream f_is=new FileInputStream(f_input);
            ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
           byte[] b_1=new byte[1024];
            int theRead=f_is.read(b_1);
            while (theRead!=-1){
             byteArrayOutputStream.write(b_1,0,theRead);
                theRead=f_is.read(b_1);
            }
            f_is.close();

        ClassReader creader=new ClassReader(byteArrayOutputStream.toByteArray());
            ClassPrinter cp=new ClassPrinter();
            creader.accept(cp,0);

            ClassWriter cwriter=new ClassWriter(0) ;

            cwriter.visit(Opcodes.V1_7,Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT+Opcodes.ACC_INTERFACE,"tmp/test",null,"java/lang/Object",null);
            cwriter.visitField(Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC,"attribute_1","I",null,new Integer(-1)).visitEnd();
            cwriter.visitField(Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC,"attribute_2","Ljava/lang/String;",null,"").visitEnd();
            cwriter.visitField(Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC,"attr_obj","Ljava/lang/String;",null,"").visitEnd();
            cwriter.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT,"compareTo","(Ljava/lang/Object;)I",null,null).visitEnd();
            cwriter.visitEnd();

            byte[] bytes=cwriter.toByteArray();

            File f3=new File("d:/test.class");
            if(f3.exists()==false){
                f3.createNewFile();
            }
            FileOutputStream fileOutputStream=new FileOutputStream(f3);
            fileOutputStream.write(bytes);
            fileOutputStream.close();



        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static   class  ClassPrinter extends ClassVisitor{
     public ClassPrinter(){
      super(Opcodes.ASM4);

     }


        @Override
        public void visit(int version, int access, String name, String signature, String supername, String[] interfaces) {
          System.out.println("当前类:版本号:【"+version+"】,名称:【"+name+"】,签名:【"+signature+"】,父类:【"+supername+"】,接口如下:");
            if(interfaces!=null){
                for (String tmp1:interfaces){
                    System.out.print("【"+tmp1+"】");
                }
                System.out.println();
            }

            System.out.println("class "+name+" extends "+supername+"{");
        }


        @Override
        public void visitSource(String source, String debug) {

        }

        @Override
        public void visitOuterClass(String owner, String name, String desc) {

        }

        @Override
        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
          return null;
        }

        @Override
        public void visitAttribute(Attribute attr) {

        }

        @Override
        public void visitInnerClass(String name, String outerName, String innerName, int access) {

        }

        @Override
        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {

            System.out.println("  "+desc+"  "+name);
            return null;
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {

            System.out.println("  "+name+"  "+desc);
            return null;
        }

        @Override
        public void visitEnd() {

            System.out.println("}");
        }
    }
}

生成自定义类以后如何加载到jvm上面?继承classloader,利用里面的defineClass来加载字节码,下面有一个例子:

    public static  class myClassLoader1 extends  ClassLoader{

                 public Class  LoadDefineClass(String name,byte[] byteCodes,int offset,int len){
            return this.defineClass(name,byteCodes,offset,len);
        }

    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值