用BCEL设计字节码 - 直接在方法的调用处添加方法2011-01-19 BlogJava Frank_Fang这个最接近之前提出的API转换问题这个需要扫描源代码找到此类的方法调用处,然后在方法调用处的前后添加指令即将代码转换成如下形式:public class StringBuilder { public String buildString(int length) { String result = ""; for (int i = 0; i < length; i++) { result += (char)(i%26 + "a"); } return result; }
public static void main(String[] argv) { StringBuilder inst = new StringBuilder(); for (int i = 0; i < argv.length; i++) {
long start = System.currentTimeMillis(); String result = inst.buildString(Integer.parseInt(argv[i])); System.out.println("Call to buildString$impl took " + (System.currentTimeMillis()-start) + " ms.");
System.out.println("Constructed string of length " + result.length()); } } }转换代码如下:先扫描这个类中的各个方法我准备改变一下生成策略,不自己写指令了,这个自己写指令比较麻烦,但要加的代码比较多时比较容易出错,当所加的代码有if,跳转语句,自己根本就不会如何写添哪些指令,这种写类似汇编指令总是很麻烦的。先要把加的代码自己在某个类中事先用方法写好,实例方法也好,静态方法也好,方法带有参数或者有返回值,这些参数和返回值供调用方法中的局部变量来替换和使用。再要添加代码的方法的前后调用这些已经写好的方法的字节码的指令序列生成InstructionList,然后再添加到使用这个方法的指令序列中如下public class ToolUtil {
public static long printStart() { System.out.println("start start start start"); long start = System.currentTimeMillis(); return start; }
public static void printEnd(String methodname,long start){
System.out.println("Call to "+methodname+" took " + (System.currentTimeMillis()-start) + " ms."); System.out.println("end end end end end end"); } }