快速业务通道

Java编程的动态性, 第4部分: 用Javassist进行类转换 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-17
******方法的正文时使用一个 java.lang.StringBuffer 来累积正文文本(这显示了 处理 String 的构造的正确方法,与在 StringBuilder 的构造中使用的方法是相对的)。这 种变化取决于原来的方法是否有返回值。如果它 有返回值,那么构造的代码就将这个值保存 在局部变量中,这样在******方法结束时就可以返回它。如果原来的方法类型为 void ,那 么就什么也不需要保存,也不用在******方法中返回任何内容。

除了对(重命名的)原来方法的调用,实际的正文内容看起来就像标准的 Java 代码。它是 代码中的 body.append(nname + "($);\n") 这一行,其中 nname 是原来方法修改后的名字 。在调用中使用的 $ 标识符是 Javassist 表示正在构造的方法的一系列参数的方式。通过 在对原来方法的调用中使用这个标识符,在调用******方法时提供的参数就可以传递给原来 的方法。

清单 5 展示了首先运行未修改过的 StringBuilder 程序、然后运行 JassistTiming 程 序以添加计时信息、最后运行修改后的 StringBuilder 程序的结果。可以看到修改后的 StringBuilder 运行时会报告执行的时间,还可以看到因为字符串构造代码效率低下而导致 的时间增加远远快于因为构造的字符串长度的增加而导致的时间增加。

清单 5. 运行这个程序

[dennis]$ java StringBuilder 1000 2000 4000 8000 16000 Constructed string of length 1000 Constructed string of length 2000 Constructed string of length 4000 Constructed string of length 8000 Constructed string of length 16000 [dennis]$ java -cp javassist.jar:. JassistTiming StringBuilder  buildString Interceptor method body: { long start = System.currentTimeMillis(); java.lang.String result = buildString$impl($); System.out.println("Call to method buildString took " +   (System.currentTimeMillis()-start) + " ms."); return result; } Added timing to method StringBuilder.buildString [dennis]$ java StringBuilder 1000 2000 4000 8000 16000 Call to method buildString took 37 ms. Constructed string of length 1000 Call to method buildString took 59 ms. Constructed string of length 2000 Call to method buildString took 181 ms. Constructed string of length 4000 Call to method buildString took 863 ms. Constructed string of length 8000 Call to method buildString took 4154 ms. Constructed string of length 16000

可以信任源代码吗?

Javassist 通过让您处理源代码而不是实际的字节码指令清单而使 classworking 变得容 易。但是这种方便性也有一个缺点。正如我在 所有字节码的源代码中提到的,Javassist 所 使用的源代码与 Java 语言并不完全一样。除了在代码中识别特殊的标识符外,Javassist 还实现了比 Java 语言规范所要求的更宽松的编译时代码检查。因此,如果不小心,就会从 源代码中生成可能会产生令人感到意外的结果的字节码。

作为一个例子,清单 6 展示了在将方法开始时的拦截器代码所使用的局部变量的类型从 long 变为 int 时的情况。Javassist 会接受这个源代码并将它转换为有效的字节码,但是 得到的时间是毫无意义的。如果试着直接在 Java 程序中编译这个赋值,您就会得到一个编 译错误,因为它违反了 Java 语言的一个规则:一个窄化的赋值需要一个类型覆盖。

清单 6. 将一个 long 储存到一个 int 中

[dennis]$ java -cp javassist.jar:. JassistTiming StringBuilder  b

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号