1.初步认识反射
我们知道在Java中一切皆对象,用对象来描述Java的世界。在正常的对象操作过程中,需要先定义使用的类,再利用new关键字实例化对象进而使用。但是如果需要通过对象来取得此对象所在类的信息,怎么办呢?
可以通过Object类中的getClass()方法来获取对象所对应的类的完整信息,方法定义如下:
public final Class<?> getClass();
这里也说明了一个问题,我们用类来描述对象,比如,date对象可以用类这么描述: Date date=new Date(),而用什么类来描述Date这个类呢?
------引入 Class.java类,注意这里的Class是java.lang.Class.java类,是切切实实的类,可以用它像我们平常自定义的类一样去定义对象比如User user,使用这个Class类定义类对象:Class cls;
① Class<T>类 用来描述类或者接口的类型, 即描述类的类
② Class<T>类的实例: 是在JVM中的一份字节码
这里①也说明了getClass()的返回类型Class<T> 为什么能描述对象所对应的类的完整信息的原因。
那么既然Class是一个用于描述类的类,怎么去实例化它呢?
2.Class类对象的实例化
getClass()方法返回的类型为java.lang.Class,这个类是反射操作的源头类,即所有反射操作都需要通过此类开始。而获得此源头类(Class类)的实例Class cls的方法有三种:
①.如果已知一个实例化对象,可以调用Object.class类的getClass()方法获取这个实例化对象对应的类的Class类的描述信息;
②.不需要类的实例化对象,获取类的Class类描述信息,可以使用“类名.class”;
③.调用Class类提供的forName()方法获取实例化对象对应的类的Class类的描述信息;
掌握了上面用于描述完整类信息的Class类的3种实例化方式,就可以利用这个Class类来进行类的反射控制了!
类的反射分为三类:
(1)使用反射调用构造函数;
(2)使用反射调用方法;
(3)使用反射调用成员变量
3.在使用反射之前,我们需要来具体了解Class类的常用方法(它描述了对象对应的类的完整信息,如user对象对应User类的信息,可以通过反射操作Class cls的cls对象描述):
public static Class<?> forName(String className)//传入完整的“包.类”名称实例化Class对象
public Class[] getInterfaces() //取得一个类所实现的全部接口
public String getName() //取得反射操作类的全名,即得到一个类完整的“包.类”名称
public String geSimpletName() //取得反射操作类的类名,不包括包名称
public Package getPackage() //取得反射操作类的包名
public Class getSuperclass() //取得反射操作类的父类
public Object newInstance() //根据Class(描述的)定义的类实例化对象
public boolean isArray() //判断此class是否是一个数组
public boolean isEnum() //判断此反射操作的类是否是枚举类
public boolean isInterface() //判断反射操作的类是否是接口
public Class<?> getComponentType() //返回表示数组类型的Class
通过Class类的常用方法可以看出,在反射操作中类或接口都是利用这个源头类Class来进行包装的,Class类可以表示任意类、接口、数组、枚举等引用类型的数据组织形式、结构等。
在Class中的newInstance()方法,通过它可以利用反射实现Class类包装的类的对象实例化操作。也就是不使用关键字new也可以实例化一个类的对象;
package com.xw.mydemo;
//定义一个类
class Book{
...
public Book(){
System.out.println("构造方法");
}
...
@override
public String toString(){
return "《我和我的祖国》"
}
}
public class BookTest{
public static void main(String[] args) throws Exception{
//获得Book类的描述类Class对象cls
Class<T> cls=Class.forName("com.xw.mydemo.Book");
Object obj=cls.newInstance();//相当于使用new调用无参构造函数
Book book=(Book)obj;//向下转型
System.out.println(book.toString());
}
}
结果: 《我和我的祖国》
未完待续!