反射
Reflection(反射)赋予了 Java 代码从已加载的类中发现成员变量(Fields)、成员方法(Methods)和构造方法(Constructors)的能力,并可以在安全限制内使用这些反射得到的成员变量、成员方法、构造方法来操作他们对应的底层对象。
简而言之,你可以在运行状态中通过反射机制做到:
对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性。
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
这些在程序加载过程中产生的类的 Class 对象就是反射的基础。要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
类加载:
JVM首次使用某个类,这个类的信息需要加载到内存中,加载的信息有(属性、方法、构造方法、包名、父类名称…)类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class对象,用来封装类在方法区内的数据结构。* 类加载时机:
- 创建对象
- 创建子类对象
- 访问静态成员
- Class.forName()*
-
- 反射:当类首次加载到内存中,会将所有的信息存储到一个对象中,这个对象我们称之为类对象,可以使用这个类对象获得该类中所有的
- 如何获取类对象:
1.对象名.getClass()
2.数据类型.class
3.Class.forName(String classpath):通过类的全路径(包名+类名)得到这个类的类对象
Java反射框架提供以下功能:
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法(通过反射设置可以调用 private)
在运行时调用人一个对象的方法
反射的主要用途
反射最重要的用途就是开发各种通用框架
①逆向代码,例如反编译
②与注释相结合的框架
③单纯的反射机制应用框架
④动态生成类对象,运行时动态加载需要加载的对象。
1.Constructor类
方法使用此 Constructor 对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例。个别参数自动展开以匹配原始形式参数,原始参考参数和参考参数都需要进行方法调用转换。
Constructor[] getConstructors():获取所有public修饰的构造方法 Constructor[] getDeclaredConstructors():获取所有的构造方法
Constructor getConstructor(Class<?>... parameterTypes):获取指定当个公开构造方法 ConstructorgetDeclaredConstructor(Class<?>… parameterTypes):获取指定的构造方法
Constructor类中创建对象的方法: Object newInstance(Object… initargs):创建对象 Constructor父类中的方法: public void setAccessible(boolean flag):值为true表示取消java语言访问检查
如何使用属性
Class类中获取属性的方法:
2. Field
每个成员变量有类型和值。java.lang.reflect.Field 为我们提供了获取当前对象的成员变量的类型,和重新设值的方法。
Field[] getFields():得到所有的公开属性 Field[] getDeclaredFields():得到所有的属性 Field getField(String name):获取public修饰的属性
Field getDeclaredField(String name):获取指定属性
Field如何为属性赋值: void set(Object obj, Object value)
如何使用方法
Class类中获取成员方法的方式:
3. Method
继承的方法(包括重载、重写和隐藏的)会被编译器强制执行,这些方法都无法反射。因此,反射一个类的方法时不考虑父类的方法,只考虑当前类的方法。
Method[] getMethods():获取所有公开方法Method[] getDeclaredMethods():获取所有方法
Method getMethod(String name, Class<?>... parameterTypes):获取指定的公开方法Method getDeclaredMethod(String name, Class<?>… parameterTypes):获取指定方法Method类中执行方法:Object invoke(Object obj, Object… args):方法执行