目前已经开发了若干个处理字节码与类文件的 java 库,其中包括我在以前的 java 编程动态性 系列中介绍的 javassist 与 bcel 库(参阅 参考资料).asm 是这种类型的另一个更新的库.与其他库不同,asm 被设计与实现为尽可能小而快.在本月的这一期文章中,我将深入研究 asm 在这一点上做得到底如何,将它与其他两个用作本系列中的示例的库进行比较.
代替反射 【程序编程相关:Java 命名约定有哪些?】
在上一期文章中,我演示了如何用运行时字节码生成来代替反射.那次,我使用了 1.4.1 的 jvm 进行测试,结果发现,生成的代码运行起来可能要比它替换的反射代码更快.除了在 asm 上采用同样的手段进行测试之外,在这一期中,我还更新了结果,用 1.5.0 的 jvm 进行测试,看看 1.5.0 中实现的性能增强是否会改变结果. 【推荐阅读:在Java中,到底什么是静态变量呢?】
设置阶段 【扩展信息:您的 Java 代码安全吗 — 还是暴露】
示例应用程序的目的是用运行时生成的代码代替反射.在我的 java 编程动态性 系列中,我已经深入介绍过这个主题.在这一期的文章中,我将对以前的材料做一个快速的背景总结,然后看看在使用 asm 代替 javassist 与 bcel 框架时,与这两者相比,asm 的性能与可用性如何.反射为在运行时访问对象与元数据提供了非常强大的机制(正如我在“java 编程动态性,第 2 部分”中讨论过的).使用反射使构建应用程序更加灵活,可以在运行时用外部信息把各个片断挂接(hook)在一起,形成一个工作配置.但是利用反射来实际访问对象通常比直接执行相同的操作慢得多.使用基于反射的方法构建应用程序,而后发现需要改进性能,这样会带来真正的问题,因为反射支持的灵活性很难以其他方式做到.classworking 技术提供了一种方法.它没有使用反射来访问对象的属性,例如,可以在运行时构建一个类来做同样的事 —— 但这样做会快许多.“java 编程动态性,第 8 部分”演示了如何用 javassist 与 bcel 这两个 classworking 框架来实现这种类型的反射替代.这篇文章采用的基本原则很简单:首先创建一个接口(该接口定义所需的函数),然后在运行时构建一个类(该类实现前面的接口,并把函数挂接到目标对象上).
清单 1 演示了这种方法.在这里,holderbean 类包含一对属性,通过使用反射来调用 get 与 set 方法,可以在运行时访问这一对属性.iaccess 接口抽象化了通过 get 与 set 方法访问 int 值属性的概念,而 accessvalue1 类则特别针对 holderbean 类的“value1”属性给出了这个接口的实现.
... 下一页