1.用途
Java源码(我们写的程序)的运行过程大致是:编译器将Java源码被编译成.Class文件,也就是常说的字节码文件,机器上的Java虚拟机再将字节码文件进行翻译 ,得到机器指令,这也是Java可以跨平台的原因(即一次编译后,可以到处运行)。
利用反射机制,可以绕过编译阶段,在运行时获取已经被编译成字节码的对象,也就是Class类对象,解析该对象以获取对象的类的全部成分,包括:构造器、成员变量、成员方法,简而言之:只要传给我一个对象,我就可以把它所属的类的成分破解出来。
反射的真正用途是作为开发框架的底层技术,比如Spring框架的IoC(反转控制)容器,其创建对象使用的就是反射,再加上对象注入技术,很好的对代码进行了解耦。
2.如何使用
2.1得到Class类对象
方式一:Class c1=Class.forName(“全类名”);
此方法用得最多,也是最狠的,因为它唯一的要求就是一个字符串,也是Spring的IoC使用到的获取Class类对象的方法,全类名是指要获取的Class类对象的类所在的全包名。举例:
Class c = Class.forName("com.learn.reflect_getclass.Student");
方式二:Class c2=类.class;
此方法需要知道目标类
方式三:Class c3=对象.getClass();
此方法需要一个目标对象
2.2获取类中的成分
类中成分包括构造器、成员变量、成员方法,接下来以构造器为例,演示从Class类对象(Student类)的获取到创建目标对象:
Class c = Class.forName("com.learn.reflect_getclass.Student");
Constructor constructor1 = c.getDeclaredConstructor();//提取无参构造器
//Constructor cf = c.getConstructor(String.class,int.class);//提取有参构造器
//若此时拿到的无参构造器是私有的,则无法利用无参构造器,故必须打开其访问权限才能用于创建对象,破坏封装性(访问权限)
constructor1.setAccessible(true);
Student s =(Student) constructor1.newInstance();//无参构造器初始化对象
//Student ss =(Student) cf.newInstance("sun",1000);//有参构造器初始化对象
System.out.println(s);
// System.out.println(ss);
上述也是Spring中IoC创建对象的过程,完全把对象的创建交给配置文件,与传统的控制对象创建的方式相反,因此叫控制反转。
2.3说明
Declared字如其名,获取的是已经申明了的成分,若不加这个关键字,只能得到访问权限为public的成分。
获取的成分除了构造器外,成员方法(Method)和成员变量(Filed)均以数组的形式返回结果。
获取得到的变量和方法后,均可对其进行赋值/取值(filed.set(对象,值)、filed.get(对象))、运行方法(method.invoke(对象,参数表)等操作。