一个Java程序可能有很多类构成。当程序运行时,JVM会从类路径中将这些类装入内存并根据代码的指示实例化出对象。但这一过程对于程序员而言似乎是透明的,只要简单的 书写如下的代码:
Foo foo = new Foo();
自然会有一个Foo对象产生。通过其引用(reference),即可对其进行使用。但有些时候,程序员不满足这样简单的对象使用方式。
例如,可以设想这样的情形:Struts里面的
有一个名为Action的类,定义了一个名为execute方法。它有很多子类,这些子类按照特定的业务要求重写了execute方法。现在需要在 程序中创建一个Action的子类对象并调用其execute方法,这看起来很简单;但如果规定这个子类的类名不是固定的写在程序里(按照程序员的话是 “写死在代码里”)
而是通过配置文件的方式在程序运行的时候动态读入,事情就会变的复杂。假设读入的类名保存在字符串变量className中,我们不能 写出如下的代码:
String className = ...// 程序运行时从配置文件中读入
Action action = new className() // 编译错误(而且是很可笑的错误)
道理很简单。
new关键字后面只能明确的写出要实例化的类的名称,而不能是一个变量!
所幸的是,当工作逼迫我们必须这样做时,可以借助Java反射机制(reflection)来实现。JDK提供了一套称为Java Reflection的API来解决这样的问题。通过它们,我们可以控制类的加载过程;动态的获取其信息(包括成员变量名、方法等)、实例化对象、调用方 法;甚至直接在内存中动态创造出类而不需要事先编制类文件。总之,反射机制可以为程序员提供更加深入的方式控制类和对象而不仅仅是简单的以透明的方式使用 它们。在某些情形下,这样做可以极大提高程序的动态特性从而提升代码的复用程度。
增加程序的灵活性。
如struts中。请求的派发控制。
当请求来到时。struts通过查询配置文件。找到该请求对应的action
然后通过反射实例化action。并调用响应method。
如果不适用反射,那么你就只能写死到代码里了。
所以说,一个灵活,一个不灵活。
很少情况下是非用反射不可的。大多数情况下反射是为了提高程序的灵活性。
因此一般框架中使用较多。因为框架要适用更多的情况。对灵活性要求较高。