快速业务通道

Java编程的动态性,第8部分: 用代码生成取代反射 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-17

Java编程的动态性,第8部分: 用代码生成取代反射

时间:2011-04-09 IBM Dennis M. Sosnoski

从本系列前面的文章中,您了解到反射的性能比直接访问要慢许多倍,并了解了用 Javassist 和 Apache Byte Code Engineering Library (BCEL)进行classwo***ng。Java 顾问 Dennis Sosnoski 通过演示如何使用运行时 classwo***ng,来用全速前进的生成代码 取代反射代码,从而结束他的 Java 编程的动态性系列。

既然您已经看到了如何使用 Javassist 和 BCEL 框架来进行 classwo***ng ,我将展示 一个实际的 classwo***ng 应用程序。这个应用程序用运行时生成的、并立即装载到 JVM 的 类来取代反射。在综合讨论的过程中,我将引用本系列的前两篇文章,以及对 Javassist 和 BCEL 的讨论,这样本文就成为了对这个很长的系列文章的一个很好的总结。

反射的性能

在 第 2 部分,我展示了无论是对于字段访问还是方法调用,反射都比直接代码慢很多倍 。这种延缓对于许多应用程序来说不算是问题,但是总是会遇到性能非常关键的情况。在这 种情况下,反射可能成为真正的瓶颈。但是,用静态编译的代码取代反射可能会非常混乱, 并且在有些情况下(如在这种框架中:反射访问的类或者项目是在运行时提供的,而不是作 为这一编译过程的一部分提供的),如果不重新构建整个应用程序就根本不可能取代。

Classwo***ng 使我们有机会将静态编译的代码的性能与反射的灵活性结合起来。这里的 基本方法是,在运行时,以一种可以被一般性代码使用的方式,构建一个自定义的类,其中 将包装对目标类的访问(以前是通过反射达到的)。将这个自定义类装载到 JVM 中后,就可 以全速运行了。

设置阶段

清单 1 给出了应用程序的起点。这里定义了一个简单的 bean 类 HolderBean 和一个访 问类 ReflectAccess 。访问类有一个命令行参数,该参数必须是一个值为 int 的 bean 类 属性的名字( value1 或者 value2 )。它增加指定属性的值,然后在退出前打印出这两个 属性值。

清单 1. 反射一个 bean

public class HolderBean {    private int m_value1;    private int m_value2;    public int getValue1() {      return m_value1;    }    public void setValue1(int value) {      m_value1 = value;    }    public int getValue2() {      return m_value2;    }    public void setValue2(int value) {      m_value2 = value;    } } public class ReflectAccess {    public void run(String[] args) throws Exception {      if (args.length == 1 && args[0].length() > 0)  {        // create property name         char lead = args[0].charAt(0);        String pname = Character.toUpperCase(lead) +          args[0].substring(1);        // look up the get and set methods        Method gmeth = HolderBean.class.getDeclaredMethod          ("get" + pname, new Class[0]);        Method smeth = HolderBean.class.getDeclaredMethod          ("set" + pname, new Class[] { int.class });        // increment value using reflection        HolderBean bean = new HolderBean();        Object start = gmeth.invoke(bean, null);        int incr = ((Integer)start).intValue() + 1;        smeth.invoke(bean, new Object[] {new Integer

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号