1.RTTI:运行时类信息。
运行期维护类信息;
多态机制是基于RTTI实现的,而RTTI的主要功能由Class实现。
2.Class类:
Class可以理解为类的类,它包含了与类有关的信息。如果说类是对对象的抽象和集合,那么Class类就是对类的抽象和集合。程序中的每个对象,都对应有一个Class对象。也就是说,每次我们创建一个新类时,同时也就自动创建了一个Class对象(保存在完全同名的.class文件中)。而在运行期,当我们需要生成一个该类的对象时,JVM会首先检查该类型的Class对象是否已经载入。否则,JVM会在类文件中查找同名的.class文件并载入。这也意味着,在系统启动时,并不是所有的类都完全载入,而是根据需要加载。一旦该类型的Class对象载入内存,就参照它构造该类型的对象信息。
因此,不管一个类经过怎样的转型,它对应的Class对象都是一个,这样,调用抽象类方法的时候,系统总能够找到真正要调用的子类的方法。
3.反射:运行期获取类信息
反射机制提供了运行期动态获取类的信息以及动态调用对象的方法的功能。
RTTI与反射的区别:
RTTI:编译器在编译时打开和检查(.class)对象,我们可以用“普通”方式调用对象的方法;
反射:编译器在编译时无法获取.Class,所以在运行期编译和检查.Class。
在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中:
Class类:代表一个类。
Class.forName(String className)---获得给定字符串名代表的类或接口相关联的Class对象;
Constructor getConstructor(Class[] params)---获得指定参数类型的公共构造函数;
Constructor[] getConstructors()---获得类的所有公共构造函数;
Constructor getDeclaredConstructor(Class[] params)---获得指定参数类型的构造函数(public private);
Constructor[] getDeclaredConstructors()---获得类的所有构造函数(public private);
Field getField(String name)---获得指定名称的类的公共属性;
Field[] getFields()---获得类的所有公共属性
Field getDeclaredField(String name)---获得指定名称的类的属性(public private);
Field[] getDeclaredFields()---获得类的所有属性(public private);
Method[] getMethods()---获得类的所有公有方法;
Method getMethod(String methodName, Class[] params)---获得指定参数类型以及方法名的类公有方法;
Method getDeclaredMethod(String name, Class[] params)---获得指定参数类型和方法名的类方法(public private);
Method[] getDeclaredMethods()---获得类声明的所有方法;
Field 类:代表类的成员变量。
toGenericString()---获得完整的属性签名
setAccessible(Boolean)---设置可访问;
set(Object obj, Object value)---设置属性值
Method类:代表类的方法。
toGenericString()---获得完整的方法签名
setAccessible(Boolean)---设置可访问;
invoke(Object obj, new Object[]{new Integer(100),...})---执行指定对象的方法并传入参数;
Constructor 类:代表类的构造方法。
toGenericString()---获得完整的构造签名
setAccessible(Boolean)---设置可访问;
newInstance(new Class[]{.class, .class, ...})---调用构造函数生成实例(无参构造函数省略class[])
使用反射主要经过以下步骤:
一、获得你想要操作的类的Class对象:
eg.
Class c = Class.forName("reflect.test.Human");//获得Human类的Class对象
二、初始化类对象:
eg.
Human human = (Human)c.newInstance();//调用无参构造函数,获得类对象
三、调用Reflect API方法,操作类方法:
eg.
Method method = c.getDeclaredMehods(c, newClass[]{int.class, int.class});//获得类指定方法
method.invoke(c, new Object[]{new Integer[100], new Integer[200]});//执行方法,无参方法省略参数Object[]