Java编程的动态性,第7部分: 用BCEL设计字节码 - 编程入门网
{
result += (char)(i%26 + ''a'');
}
return result;
}
private String buildString(int length) {
long start = System.currentTimeMillis();
String result = buildString$impl(length);
System.out.println("Call to buildString$impl took " +
(System.currentTimeMillis()-start) + " ms.");
return result;
}
public static void main(String[] argv) {
StringBuilder inst = new StringBuilder();
for (int i = 0; i < argv.length; i++) {
String result = inst.buildString(Integer.parseInt(argv [i]));
System.out.println("Constructed string of length " +
result.length());
}
}
}
Java编程的动态性,第7部分: 用BCEL设计字节码(3)时间:2011-04-09 IBM Dennis M. Sosnoski编写转换代码 用我在 BCEL 类访问一节中描述的 BCEL API 实现添加方法计时的代码。在 JVM 指令级 别上的操作使代码比 第 4 部分 中 Javassist 的例子要长得多,所以这里我准备在提供完 整的实现之前,一段一段地介绍。在最后的代码中,所有片段构成一个方法,它有两个参数 : cgen ——它是 org.apache.bcel.generic.ClassGen 类的一个实例,用被修改的类的现 有信息初始化,和方法——要计时方法的 org.apache.bcel.classfile.Method 实例。 清单 3 是转换方法的第一段代码。可以从注释中看到,第一部分只是初始化要使用的基 本 BCEL 组件,它包括用要计时方法的信息初始化一个新的 org.apache.bcel.generic.MethodGen 实例。我为这个 MethodGen 设置一个空的指令清单, 在后面我将用实际的计时代码填充它。在第 2 部分,我用原来的方法创建第二个 org.apache.bcel.generic.MethodGen 实例,然后从类中删除原来的方法。在第二个 MethodGen 实例中,我只是让名字加上“$impl”后缀,然后调用 getMethod() 以将可修改 的方法信息转换为固定形式的 org.apache.bcel.classfile.Method 实例。然后调用 addMethod() 以便在类中添加改名后的方法。 清单 3. 添加拦截方法
清单 4 给出了转换方法的下一段代码。这里的第一部分计算方法调用参数在堆栈上占用 的空间。之所以需要这段代码,是因为为了在调用包装方法之前在堆栈帧上存储开始时间, 我需要知道局部变量可以使用什么偏移值(注意,我可以用 BCEL 的局部变量处理得到同样 的效果,但是在本文中我选择使用显式的方式)。这段代码的第二部分生成对 java.lang.System.currentTimeMillis() 的调用,以得到开始时间,并将它保存到堆栈帧中 计算出的局部变量偏移处。 您可能会奇怪为什么在开始参数大小计算时要检查方法是否是静 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |