ASM系列五 利用TreeApi 解析生成Class

编程技术  /  houtizong 发布于 3年前   168

   前面CoreApi的介绍部分基本涵盖了ASMCore包下面的主要API及功能,其中还有一部分关于MetaData的解析和生成就不再赘述。这篇开始介绍ASM另一部分主要的ApiTreeApi。这一部分源码是关联的asm-tree-5.0.4的版本。

         在介绍前,先要知道一点, Tree工程的接口基本可以完成大部分我们之前介绍的Core中的功能。但是在实际使用中更加便利,当然也会更加消耗时间和性能。完成一个简单的生成编译后的Class字节码的任务,可能会花费多余Core30%的时间,同时也会消耗更多内存。但是通过下面的介绍,相信在选择用哪种Api上,我们也会做出自己的取舍和判断。

一、生成编译后的Class

 

        生成和转换一个编译后的Java类在TreeApi 中,主要借助ClassNode来完成。我们先一览一下ClassNode的一部分内容。

public class ClassNode  extends ClassVisitor {public int version;public int access;public String name;public String signature;public String superName;public List<String> interfaces;public String sourceFile;public String sourceDebug;public String outerClass;public String outerMethod;public String outerMethodDesc;public List<AnnotationNode> visibleAnnotations;public List<AnnotationNode> invisibleAnnotations;public List<Attribute> attrs;public List<InnerClassNode> innerClasses;public List<FieldNode> fields;public List<MethodNode> methods;…}

    同样,也有FieldNode MethodNode。这两个Api后续再详细介绍。可以看出ClassNode的这些公有成员可以让我们直接访问,可以通过初始化这些成员来生成编译后的Class,而不是像ClassVisitor那样,只能调用visitvisitField等方法来实现。下面简单看个例子,这个例子和之前我们那篇http://yunshen0909.iteye.com/blog/2219310 中一样,只是使用的API不同:

package asm.tree;import org.objectweb.asm.ClassWriter;import org.objectweb.asm.Opcodes;import org.objectweb.asm.tree.ClassNode;import org.objectweb.asm.tree.FieldNode;import org.objectweb.asm.tree.MethodNode;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;/** * Created by yunshen.ljy on 2015/7/12. */public class GenerateClasses {    public static void main(String[] args) throws FileNotFoundException {        ClassWriter cw = new ClassWriter(Opcodes.ASM5);        ClassNode cn = gen();        cn.accept(cw);        File file = new File("ChildClass.class");        FileOutputStream fout = new FileOutputStream(file);        try {            fout.write(cw.toByteArray());            fout.close();        } catch (IOException e) {            e.printStackTrace();        }    }    private static ClassNode gen() {        ClassNode classNode = new ClassNode();        classNode.version = Opcodes.V1_8;        classNode.access = Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT;        classNode.name = "asm/core/ChildClass";        classNode.superName = "java/lang/Object";        classNode.interfaces.add("asm/core/ParentInter");        classNode.fields.add(new FieldNode(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "zero", "I",                null, new Integer(0)));        classNode.methods.add(new MethodNode(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "compareTo",                "(Ljava/lang/Object;)I", null, null));        return classNode;    }}

 

   上述例子,我们借助ClassWriter来输出字节数组是为了方便查看和对比生成的Class文件和我们之前用ClassVisitor是否达到同样的效果。ClassNode accept方法在第三部分展开介绍一下。同时,我们注意到,因为我们是可以直接访问类的共有变量的,所以也就不需要像ClassVisitor那样讲究调用顺序。用ClassNode 生成各个元素可以是无序访问,在一些情况确实是遍历,当然损失的就是性能。

 

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客