JAVA字节码文件操作技巧
从上面的图表中分析可以看到,对于一般的操作Java字节码要求(实际上是能够满足笔者100%的要求),综合考虑功能,性能,可用性,易用性,使用Java字节码框架来操作Java字节码是最佳的选择。
下面来了解一下都有哪些开源操作JavaJava字节码的框架:
Javassist;
cglib;
SERP;
Packagegnu.bytecode;
Cojen;
Jdec;
BCEL;
ObjectWebASM;
JClassLib;
TroveClassFileAPI;
Jiapi;
ClassfileReader&Writer;
JBET;
Retroweaver;
Jen;
Soot
这里重点介绍一下ASM,因为下面将使用ASM框架进行Java字节码修改。
ASM这个Java字节码操控框架能被用来动态生成类或者增强既有类的功能。ASM可以直接产生二进制class文件,也可以在类被加载入Java虚拟机之前动态改变类行为。Javaclass被存储在严格格式定义的.class文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及Java字节码(指令)。ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。下图对当前接触常用的操作Java字节码框架进行了一个比较:
?
ASM的几个特性:
1.JAVABased.
ASM是基于JAVA的,即用JAVA实现的。
2.Visitor模式.
对于ASM来说,Javaclass被描述为一棵树;使用“Visitor”模式遍历整个二进制结构。
3.复杂性低.易学易用.
ASM提供了更为现代的编程模型,降低了操作Java字节码的复杂性,使用事件驱动的处理方式使得用户只需要关注于对其编程有意义的部分,而不必了解Java类文件格式的所有细节:ASM框架提供了默认的“responsetaker”处理这一切。
4.较高的性能
对Java字节码进行操作的同时尽量减小的性能的损失(性能的损失是不可避免)。
这里来介绍一下ASM组成及顺序图:

Corepackage提供了一个读写、修改Javabytecode的API,并且为其它的package定义了依据。这个package对于生成Javabytecode、实现大多数的bytecode变换而言意义重大。
Treepackage提供了Javabytecode的内存表示法。
Analysispackage提供了基本的数据流分析和类型检查算法,它们将用于在treeoackage中存储Java方法bytecode。
Commonspackage(包含在ASM2.0中)提供了一些常用的bytecode转换和用于简化bytecode生成的适配器。
Utilpackage包含了一些帮助类和简单的bytecode验证器,它们将有助于开发或者测试。
XMLpackage提供了一个用于在bytecode和XML之间进行转换的适配器,和一些允许使用XSLT定义bytecode转换的兼容SAX的适配器。
顺序图:
?
Demo
这里我们来实现这样一个功能:在不能改变原代码功能的前提下,对于一个特定类的特定方法有没有被测试过,以HelloTaobao类中方法helloHeyun为例。
类HelloTaobao:
?
FROM:http://developer.51cto.com/art/201009/227243_2.htm