Java反射机制

转自: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中也运到了动态代理机制,有兴趣的朋友可查找相关资料。