反射是什么
反射(Reflection)是Java程序开发语言的特征之一,它允许运行中的Java程序获取自身的信息,并且可以操作类或对象的内部属性。主要是指程序可以访问、检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
Oracle官方对反射的解释:
Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fields, methods, and constructors to operate on their underlying counterparts, within security restrictions.
The API accommodates applications that need access to either the public members of a target object (based on its runtime class) or the members declared by a given class. It also allows programs to suppress default reflective access control.
简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。
使用反射有如下优缺点
优点:
- 能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性
- android的开发中,反射使得在版本和机型的适配兼容性上提供了大的方便
缺点:
- 使用反射的性能较低
- 使用反射相对来说不安全(另外,对于混淆类的情况很可能对应不上)
- 破坏了类的封装性(可以通过反射获取这个类的私有方法和属性 )
因此,反射有利有弊,需要分具体场景来择取是否真的需要反射!!!
java虚拟机实例化一个对象的流程描述:
假如你写了一段代码:Object o = new Object();
运行了起来!
其内部运行流程为如下描述:
首先JVM会启动,你的代码会编译成一个.class文件,然后被类加载器加载进jvm的内存中,你的类Object加载到方法区中,创建了Object类的class对象到堆中,注意这个不是new出来的对象,而是类的类型对象,每个类只有一个class对象,作为方法区类的数据结构的接口。jvm创建对象前,会先检查类是否加载,寻找类对应的class对象,若加载好,则为你的对象分配内存,初始化也就是代码:new Object()。
以上流程来自于这里的描述: https://www.zhihu.com/question/24304289
JDK反射介绍
在这里先看一下sun为我们提供了哪些操作反射的类:
java.lang.Class; //类对象
java.lang.reflect.Constructor; //构造器对象
java.lang.reflect.Field; //属性对象
java.lang.reflect.Method; //方法对象
java.lang.reflect.Modifier; //修饰符对象
注:Modifier
可用来描述abstract
、final
、interface
、native
、private
、protected
、public
、static
、strictfp
、synchronized
、transient
、volatile
等。
JDK反射具体有如下用法:
注意区分带不带Declared
字样的方法名区别:
- 带有
Declared时
表示获取与public
、private
、protect
修饰无关的所有对象,但不能是继承来的; - 不带
Declared
时,表示只获取public
标识符修饰的对象,且还包括从超类继承来的public
对象。
- 获取对象构造器
//获得指定参数类型params的public构造函数
Constructor getConstructor(Class[] params);
//获得类的所有public构造函数
Constructor[] getConstructors();
//获得使用指定参数类型params的