如果我们要在程序运行时动态地加载某个类,我们应该如何做呢?将要用到Reflection API,通过这种机制,我们可以而不知道类的名字,而得到类的所有函数的名字和类型,以及所有的数据成员的格式,而且,我们可以通过某些机制来动态的调用。通过Reflection API,可以实现强大的功能,就如同一个巨大的黑洞,可以接受一切东西,不管你是什么形态。事实上,编译器,GUI,甚至是接口,都用到了Reflection。
Reflection的基本功能是什么呢?1.运行时生成类的实例(instance),2.执行期间调用方法(Method),3.运行时修改数据成员(field)。
要实现这么强大的功能,首先必须了解Class类,Class在这里是单独的一个类,它位于java.lang包中,它用以描述程序的接口和类等信息,它本身没有构造函数,但是可以通过以下三种方法获得一个Class类的对象,它与某一个类或接口相关联。
对于任何类的对象,可以通过 Class object=对象名.getClass()的方式,getClass()函数是Object类中的成员函数。
Class object=Class.forName(类名);forName()是Class类的一个静态成员函数
通过Class object=类名.class语法,对于基本数据类型(Primitive)的封装类,可以通过类名.TYPE语法,这一点比较特殊。
事实上,如果一个Class类的对象关联了某一个类,那么可以通过Class类的成员newInstance()来利用关联类的默认构造函数(即无参构造函数)来声明该类的一个对象。但是如果要调用带参数的构造函数,就要用到其他的方法。具体的步骤如下:
1.Class 对象与某类相关联。
声明用一个Class数组,(如parameter[])包含需要调用的构造函数所需要的参数类型信息
调用Class类的getConstrutor(parameter)来寻找合适的构造函数,把他的值返回给一个Construtor的对象(此处设为cons),Constructor类在java.lang.reflect包下,需要单独加载。
声明一个Object类的对象数组(此处设为 arg[]),这是实际参数。
利用cons.newInstance(arg),即可获得一个对应类的对象。(该函数位于java.lang.reflect.Constructor类中)
动态调用成员函数的方法与之类似,不过对应的Constructor对象必须更改为一个Method类对象,Method类也在java.lang.reflect包中。它可以通过调用java.lang.reflect.Method类下的invoke(对象名,实参),形式调用某个函数,这里并不需要声明返回值,这一切交给JVM完成。它返回的值也是唯一确定的。
动态修改数据成员时,首先调用Class的getField()并指定field名称。获得特定的Field object之后便可直接调用Field的get()和set().
以下代码除了动态调用函数和动态修改数据成员外,实现了全部本文提到的内容,并在jdk1.5中运行通过。
import java.lang.reflect.*;
class ReflectTest
{
public static void main(String[] args)
{
if(args.length!=0)
{
Class flag=null;
try
{
flag=Class.forName(args[0]);
}
catch(Exception e)
{
e.printStackTrace();
}
Constructor[] cons=null;
try
{
cons=flag.getDeclaredConstructors();
}
catch(Exception e)
{
e.printStackTrace();
}
Method[] meth=null;
try
{
meth=flag.getDeclaredMethods();
}
catch(Exception e)
{
e.printStackTrace();
}
for(int i=0;i<cons.length;i++)
{
System.out.println(cons[i].getName());
}
for(int i=0;i<meth.length;i++)
{
System.out.println(meth[i].getName());
}
System.out.println("---------------------------");
Object o1=null;
try
{
o1=flag.newInstance();
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(o1.toString());
Class[] parameters=new Class[]{String.class};
Constructor constr=null;
try
{
constr=flag.getConstructor(parameters);
}
catch(Exception e)
{
e.printStackTrace();
}
Object o2=null;
Object[] o3=new Object[]{"HongMei"};
try
{
o2=constr.newInstance(o3);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(o2);
}
else
{
System.out.println("We cant got parameter");
}
}
}
class Cigarette
{
static
{
System.out.println("Class Cigarette is loaded now");
}
Cigarette()
{
}
public Cigarette(String str)
{
this.logo=str;
}
public void smoke()
{
System.out.println("smoke feels good");
}
public void lighterType(String type)
{
System.out.println(type);
}
String logo;
public String toString()
{
return "Cigarette type is "+logo;
}
}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1746387
posted on 2007-08-31 10:20
fly 阅读(268)
评论(0) 编辑 收藏 所属分类:
java学习