前面CoreApi的介绍部分基本涵盖了ASMCore包下面的主要API及功能,其中还有一部分关于MetaData的解析和生成就不再赘述。这篇开始介绍ASM另一部分主要的Api。TreeApi。这一部分源码是关联的asm-tree-5.0.4的版本。
在介绍前,先要知道一点, Tree工程的接口基本可以完成大部分我们之前介绍的Core中的功能。但是在实际使用中更加便利,当然也会更加消耗时间和性能。完成一个简单的生成编译后的Class字节码的任务,可能会花费多余Core的30%的时间,同时也会消耗更多内存。但是通过下面的介绍,相信在选择用哪种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那样,只能调用visit、visitField等方法来实现。下面简单看个例子,这个例子和之前我们那篇ASM(一) 利用Core API 解析和生成字节码 中一样,只是使用的API不同: