转自:http://blog.csdn.net/gaojuvip/archive/2008/09/24/2971340.aspx
Java反射机制主要提供了如下功能: 在运行时判断任何一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任何一个类所具有的成员变量和方法;
在运行时调用任何一个对象的方法;
生成动态代理。
Java Reflection API简介 在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中:
Class类:代表一个类;
Field类:代表类的成员变量;
Method类:代表类的方法;
Constructor:代表类的构造方法;
Array:提供了动态创建数组,以及访问数组元素的静态方法。
二. 在远程方法调用中运用反射机制 让我们来看一个在远程调用方法中调用运用反射机制的例子。该例的服务端SimpleServer接收客户端SimpleClient发送的Call对象,该Call类型对象包括要调用的远程对象的类名、方法名、参数类型和参数值信息。而服务端SimpleServer在接收到该对象时,调用指定类名的指定方法,并加组装了返回值的Call类型对象返回给客户端SimpleClient。若不存在所指定的类或方法,则将异常放入Call类型对象的result属性中,返回给客户端。下面让我们来看看这个例子:
Call对象 Call对象包含类名、方法名、参数类型、参数值信息和返回结果信息,是用来在客户端和服务端进行信息交互的对象。其代码如下:
服务端SimpleServer 服务端建立一个ServerSocket,一直读取客户端发送来的消息,并传入参数到指定的方法,调用该方法,并将返回结果设置到Call类型对象的result属性中,若出现异常情况时,将异常放入result属性中,并将改变后的Call类型对象返回。其代码如下所示:
客户端SimpleClient 客户端发送组装好的Call对象给服务端,并读取指定方法的返回结果。其完整代码如下:
package remotecall;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
/** *//**
*客户端类.
*/
远程类HelloService及其实现类HelloServiceImpl 为了测试上面的功能,还需要模拟一个远程对象所属的类,本例的HelloService接口具有两个方法,echo()和getTime()。两者的内容如下:
HelloService的内容:
HelloServiceImpl的内容:
在测试时,我们首先运行服务端SimpleServer,将服务端启动起来,接着将客户端SimpleClient启动,可在控制台看到如下信息:
客户端的信息如下:
echo: Hello,阿蜜果
java.lang.ClassNotFoundException: remotecall.HelloEcho
服务端的信息如下:
服务器启动...
className=remotecall.HelloService,methodName=echo
className=remotecall.HelloEcho,methodName=echo
三.代理模式 代理模式是常用的Java设计模式,它的特征是代理类和委托类有相同的接口。代理类主要负责为委托类预处理消息、过滤信息、把消息转发给委托类,以及事后处理信息等。代理类和委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
根据代理类的创建时期,可将其分为两类:
静态代理类:由程序员创建或由特定工具自动生成源代码;
动态代理类:在程序运行时,运用反射机制创建而成。
静态代理类 请参考代理模式的一些实现实例,在此不再详述。
动态代理类 动态代理类不仅简化了编程工作,而且提高了软件系统的扩展性,因为Java反射机制可以生成任意类型的动态代理类。java.lang.reflect类和InvocationHandler接口提供了生成动态代理类的能力。与之相关的方法是:getProxyClass()和newProxyInstance()方法。下面让我们来看一个动态代理类的简单例子:
运行后可看到这个代理类是动态生成的。在Spring的AOP中也运到了动态代理机制,有兴趣的朋友可查找相关资料。