Java 编程的动态性,第 8 部分: 用代码生成取代反射
从本系列前面的文章中,您了解到反射的性能比直接访问要慢许多倍,并了解了用 Javassist 和 Apache
Byte Code Engineering Library (BCEL)进行classworking。Java 顾问 Dennis
Sosnoski 通过演示如何使用运行时 classworking,来用全速前进的生成代码取代反射代码,从而结束他的 Java 编程的动态性
系列。
既然您已经看到了如何使用 Javassist 和 BCEL 框架来进行 classworking (请参阅
本系列以前的一组文章
),
我将展示一个实际的 classworking 应用程序。这个应用程序用运行时生成的、并立即装载到 JVM 的类来取代反射。在综合讨论的过程中,我将引用本系列的前两篇文章,以及对
Javassist 和 BCEL 的讨论,这样本文就成为了对这个很长的系列文章的一个很好的总结。
反射的性能
在
第
2 部分
,
我展示了无论是对于字段访问还是方法调用,反射都比直接代码慢很多倍。这种延缓对于许多应用程序来说不算是问题,但是总是会遇到性能非常关键的情况。在这
种情况下,反射可能成为真正的瓶颈。但是,用静态编译的代码取代反射可能会非常混乱,并且在有些情况下(如在这种框架中:反射访问的类或者项目是在运行时
提供的,而不是作为这一编译过程的一部分提供的),如果不重新构建整个应用程序就根本不可能取代。
Classworking 使我们有机会将静态编译的代码的性能与反射的灵活性结合起来。这里的基本方法是,在运行时,以一种可以被一般性代码使用的方式,构建一个自定义的类,其中将包装对目标类的访问(以前是通过反射达到的)。将这个自定义类装载到
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
相关文档:
JAVA相关基础知识
1、面向对象的特征有哪些方面
2、String是最基本的数据类型吗?
3、int 和 Integer 有什么区别
4、String 和StringBuffer的区别
5、运行时异常与一般异常有何异同?
6、说出Servlet的生命周期,并说出Servlet和CGI的区别。
7、说出ArrayList,Vector, LinkedList的存储性能和特性
8、EJB是基于哪些 ......
Socket传输模式
Sockets有两种主要的操作方式:面向连接的和无连接的.面向连接的sockets操作就像一部电话,他们必须建立一个连接和一人呼叫.所有的事情在到达时的顺序和他们出发时的顺序时相同.无连接的sockets操作就像是个邮件投递,,没有什么确保,多个邮件可能在到达时的顺序和出发时的顺序不相同.
到底用哪种模式是邮应 ......
//** **********创建工作簿************ */
WritableWorkbook workbook = Workbook.createWorkbook(new File("d:/test.xls"));
/** *//** **********创建工 ......
package com;
import java.util.*;
public class WhatDay {
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
c.setTime(new Date(System.currentTimeMillis()));
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
switch (dayOfWeek) {
ca ......