一、什么是反射
反射,即Reflection,通常是指程序可以访问、检测和修改它本身状态或行为的一种能力。
具体说来,是在运行状态时,对于任意一个类或对象,能够知道和操作它的任意方法和属性。
需要注意的是,反射是一种非常规手段,反射有风险,应用需谨慎。
二、为什么要用反射
为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念:
- 静态编译:在编译时确定类型,绑定对象,即通过。
- 动态编译:运行时确定类型,绑定对象。
反射的初衷不是方便你去创建一个对象,而是让你在写代码的时候可以更加灵活,降低耦合,提高代码的自适应能力.
利用反射机制,我们可以动态调用一些protected甚至是private的方法或类,这样可以满足我们一些场景下的特殊需求。
三、Reflection API 几个重要类
- Class:类
- Field:类的成员变量
- Method:类的方法
- Constructor:类的构造方法
四、如何使用反射
1、获取Class对象
方法一:类名.class
Class<?> cls = Student.Class();
Student student =(Student)cls.newInstance();
方法二:Class.forName(类路径)
Class<?> class = Class.forName("com.kwmax.Student"); //forName(包名.类名)
Student student = (Student)class.newInstance();
方法三:对象.getClass()
Student stu1 = new Student();
Class<?> cls = student.getClass();
student stu2 = (Student)cls.newInstance();
三种方法的区别:
方法一不执行静态块和动态构造块,
方法二执行静态块、不执行动态构造块,
方法三需要创建对象,静态块和动态构造块均会执行
2、获取类属性
//下面两种可以获取到public属性
mClass.getField(属性名);
mClass.getFields();
//返回指定名的属性,不论公共还是私有
mClass.getDeclaredField(属性名);
//返回所有属性,不论公共还是私有
mClass.getDeclaredFields();
3、获取类方法
//下面两种可以获取到public方法
mClass.getMethod(方法的名称);
mClass.getMethods();
//返回指定名的方法,不论公共还是私有
mClass.getDeclaredMethod(方法的名称);
//返回所有属性,不论公共还是私有
mClass.getDeclaredMethods();
4、获取构造方法
//下面两种可以获取到public方法
mClass.getConstructor(可变参数集合);
mClass.getConstructors();
//返回指定名的构造方法,不论公共还是私有
mClass.getDeclaredConstructor(参数类名);
//返回所有构造方法,不论公共还是私有
mClass.getDeclaredConstructors();
5、实例化对象
除了第一种方法,获取类对象后实例化,还可以通过构造方法实例化
constructor.newInstance(可变参数);
6、一些可能用到的操作方法:
//获取到反射的权限,如果为私有的则需要设置为true
constructor.setAccessible(true);
method.setAccessible(true)
//设置属性值
field.set(Objkect obj,Object value);
//获取属性对象
field.get(Object)
例子:Person p = (Persion)filed.get(对象);
//获取这个类的父类
getSuperclass()
//获取这个类实现的所有接口
getInterfaces()
//获取方法的返回类型
getReturnType()