我们都知道,一个.java文件可以编译生成.class文件;而在.class文件中包含的就是字节码(bytecode)数据。
那么,Java ASM是什么呢?Java ASM就是一个操作字节码(bytecode)的类库(Java Library)。我们也可以理解成:Java ASM是一个可以操作.class文件的类库。
下文分成两个主要部分,第一部分是对ASM进行介绍,对它进行了解;第二部分是如何学习ASM技术,有哪些可以参考的资料。
了解ASM
本部分主要介绍ASM能够做什么和它的内部结构。
从外部视角看ASM
首先,站在Java ASM之外的视角,来看待ASM。我们知道这样一句诗“不识庐山真面目,只缘身在此山中”;也就是说,有的时候,离一件事物太近,反而看不清它的全貌;我们适当的离它远一点,才能知晓它大概的轮廓。
从外部视角看ASM,看看它可以用来做什么、有哪些应用。概括的来说,Java ASM主要有两个用途,一方面可以动态的生成类文件(Class Generation),另一方面可以对已有的类文件进行转换(Class Transformation)。
第一方面,动态的生成类文件(Class Generation)是指什么意思呢?一般情况下来说,.class文件是由.java文件编译得到的;但是,如果我们借助于Java ASM,就不需要去写.java文件,就能够直接生成.class文件的内容。那么,动态的生成类文件(Class Generation)有什么样的应用场景呢?在Java 8之后引入了Lambda表达式,而Lambda表达在调用实现上就是通过使用Java ASM动态生成类文件(Class Generation)的功能来实现的。
第二方面,对已有的类文件进行转换(Class Transformation)是指什么意思呢?它就表示可以对.class文件中的类层面的信息、字段层面的信息和方法层面的信息进行修改,让原来的.class文件具体的功能发生变化。那么,对已有的类文件进行转换(Class Transformation)有哪些应用场景呢?它可以帮助我们实现AOP(Aspect Oriented Programming,面向切面编程)功能,例如,计算方法的运行时间、打印方法的参数和返回值等。
从内部视角看ASM
接着,站在Java ASM之内的视角,来看待ASM。我们也知道这样一句诗“纸上得来终觉浅,绝知此事要躬行”;也就是说,如果总是站在远处,得到的总是一个模糊的印象,似乎你对它有所了解,但知道的却很有限;这个时候,你需要靠近它,看看它究竟蕴藏着什么样的美妙“风景”。
从内部视角看ASM,看看它有哪些组成部分。Java ASM由Core API和Tree API两部分组成;这两个部分的关系:Core API是基础,而Tree API是在Core API的基础上搭建起来的。从时间演进的历史来看,Java ASM在刚开始出现的时候,只有Core API的内容;后来,随着人们的需求增加,ASM就需要添加新的类来满足这些需求,于是就逐渐产生了Tree API的内容。
更进一步的说,Java ASM是由5个jar文件组成,分别是asm.jar、asm-commons.jar、asm-util.jar、asm-tree.jar和asm-analysis.jar。其中,Core API包括了asm.jar、asm-commons.jar和asm-util.jar这三个文件;而Tree API包括了asm-tree.jar和asm-analysis.jar这两个文件。
如何学习ASM
本部分主要介绍学习ASM知识的顺序及相关参考资料。
学习顺序
谈到学习顺序,我们就借助于第一部分中提到的“外部视角”和“内部视角”来讲一讲。
从内部视角来看,应该先学Core API,后学Tree API。因为Core API是基础,而Tree API是在Core API的基础上构建起来的。如果先学Tree API,这就无异于“还没学会走就开始跑”的情况,这样急于求成的心态似乎是目标明确,但是无形中增加了学习的难度,也无法构建起完整的知识体系。
从外部视角来看,应该先学动态的生成类文件(Class Generation),后学对已有的类文件进行转换(Class Transformation)。为什么是这样一个学习顺序呢?因为在学习动态的生成类文件(Class Generation)的过程,其实就是让你去开始学习和熟悉ASM API和.class文件结构的过程,知识是一点点积累起来的;而对已有的类文件进行转换(Class Transformation)就是利用ASM API和.class文件结构的知识去对已有的.class进行修改。举个形象的例子,动态的生成类文件(Class Generation)的过程就像是你学习建造火箭的知识,并造一个火箭简单原型的过程;而对已有的类文件进行转换(Class Transformation)的过程就像是你要对别人已经建造好的火箭进行修改的过程。
参考资料
如果盲目地从网上寻找资料,可能找到参考资料的质量参差不齐,浪费时间不说,且学习效果甚微。那么,在这里我们列出三份有高质量的参考资料,希望能够帮助到大家:
第一份资料,《Java ASM系列一:Core API》视频教程,在B站可以进行搜索,其特点是对Java ASM中Core API进行系统的介绍,并且配有相关文档和源代码,是完全免费的。
第二份资料,《asm-guide.pdf》,这是ASM官网提供的参考文档,有很大的参考价值,资料地址为:https://asm.ow2.io/asm4-guide.pdf
第三份资料,《The Java Virtual Machine Specification》,这是Oracle官方的JVM文档,因为在学习ASM的过程,要不可避免的查询JVM官方文档第6章的内容,资料地址:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html