反射
首先我们先理解反射机制
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制
Java反射提供的功能
- 在运行时判断任何一个对象所属的类
- 在运行时构造任何一个类的对象
- 在运行时判断任何一个类所具有的成员变量和方法
- 在运行时调用任何一个对象的成员变量和方法
- 生成动态代理
深入理解反射机制
反射中包含了“反”,那么就先知道什么是正射
一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的,于是我们直接对这个类进行实例化,之后使用这个类实例进行操作
Apple apple= new Apple(); //直接初始化 [正射]
apple.setPrice(4);
上面这样子进行类对象的初始化,我们可以理解为[正]
而反射则是一开始并不知道我要初始化的类对象是什么,自然也就无法使用new关键字来创建对象
首先考虑下面的语句:
Person p=new Person();
整个创建对象的过程为:
通过new创建实例和反射创建实例,都绕不开Class对象,通过字节码.class文件创建Class对象的步骤如下:
- 首先根据文件位置,IO读取.class文件,得到字节数据
- 构建字节数组
- 根据字节,创建Class对象
获取反射中的Class对象
在反射中,要获取一个类或调用一个类的方法时,我们首先要获取到该类的Class对象,在JavaAPI中,获取Class类对象有三种方法:
第一种,使用Class.forName静态方法,当你知道该类的全路径名时,你可以使用该方法获取Class类对象
Class clazz=Class.forName("java.lang.string");
第二种,使用.class方法,这种方法只适合在编译前就知道操作的Class
Class clazz=String.class;
第三种,使用类对象的getClass()方法
String str=new String("Hello");
Class clazz=str.getClass();
通过反射创建类对象
通过反射创建类对象主要有两种方式:通过Class对象的ewInstance()方法,通过Constructor对象的newInstance()方法
第一种:通过Class对象的newInstance()方法
Class clazz=Apple.class;
Apple apple=(Apple)clazz.newInstance();
第二种:通过Constructor对象的newInstance()方法
Class clazz=Apple.class;
Constructor constructor=clazz.getConstructor();
Apple apple=(Apple)constructor.newInstance();
通过Constructor对象创建类对象可以选择特定构造方法,而通过Class对象则只能使用默认的无参构造方法
通过反射获取类属性、方法、构造器
我们通过Class对象的getFields()方法可以获取Class类的属性,但无法获取私有属性,而如果使用Class对象的==getDeclaredFields()==方法则可以获取包括私有属性在内的所有属性
与获取类属性一样,当我们去获取类方法、类构造器时,如果要获取私有方法或者私有构造器,则必须使用有declared关键字的方法
相关参考反射机制
JDK动态代理
具体参考浅谈JDK动态代理