如果不知道一个类的确切类型,RTTI(运行时类型信息)可以告诉我们。但是,这个类必须在编译时是已知的。这样无形给编程增加了一个限制,如果有下面的情况:假设你要获取一个并不在你的程序空间的对象的引用,例如:从硬盘或者网络上获取一个字符串,并且这些字符串是一个个的类名称。这个类在编译器编译后很久才会出现,那么怎么才能使用这些类!这样就产生程序了运行时,获取类信息的需求。运行时获取类信息的类的动态加载可以提供跨网络的远程平台上创建和运行对象的能力。
JAVA的反射机制是一直允许程序运行时动态加载和使用类的机制,每一个load到内存的class都是一个个的对象。近距离方法这些对象,它们有方法和属性;每一个方法、属性又都是对象。
Class类和java.lang.reflect类库一起实现了反射的概念。java.lang.reflect类库包含Field,Method和Constructor类,这些类都是JVM运行时创建的,用来表示未知类里面的成员。这样就可以用Constructor创建新对象,用get()和set()读取和修改与Field对象关联的字段,用invoke ()调用与Method对象关联的方法。
程序实例:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.sun.java.util.*;
public class TestReflection {
/**
* @param args
* @throws IllegalAccessException
* @throws InstantiationException
* @throws ClassNotFoundException
* @throws ClassNotFoundException
* @throws InvocationTargetException
* @throws IllegalArgumentException
*/
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
String str = "T";
//T t = new T(); //此方法不够灵活!
Class c = Class.forName(str); //名字叫String 的类装载到内存;
Object o = c.newInstance(); //new 一个T的对象;抛非法访问的对象
Method[] methods = c.getMethods();
for(Method m : methods){
System.out.println(m.getName());
if(m.getName().equals("mm")){
m.invoke(o);
}
}
}
}
class T {
int i ;
String s;
static {
System.out.println("T loaded");
}
public T() {
System.out.println("T constructed!");
}
public void m1(int i){
this .i = i;
}
public String gets(){
return s;
}
public void mm() {
System.out.println("mm invock");
}
}