1.反射概述java
1.1 反射概述程序员
1.2 获取class文件对象的三种方式模块化
1.3 反射经常使用的方法介绍性能
1.4 反射的定义spa
1.5 反射的组成插件
1.6 反射的做用有哪些对象
2.反射的相关使用继承
2.1.1 经过反射获取无参构造方法并使用接口
2.1.2 经过反射获取带参构造方法并使用ip
2.1.3 经过反射获取私有构造方法并使用
2.1.4 经过反射获取成员变量并使用
2.1.5 经过反射获取无参无返回值成员方法并使用
2.1.6 经过反射获取带参无返回值成员方法并使用
2.1.7 经过反射获取带参带返回值成员方法并使用
2.1.8 经过反射获取无参带返回值成员方法并使用
3.相关知识点
3.1.1 设置setAccessible(true)暴力访问权限
3.1.2 获取Filed两个方法的区别
3.1.3 获取Field的类型
3.1.4 Method获取方法名,获取方法参数
3.1.5 Method方法的invoke()方法执行
关于连接
1.技术博客汇总
2.开源项目汇总
3.生活博客汇总
4.喜马拉雅音频汇总
5.程序员聊天笔记汇总
5.其余汇总
0.1 被反射的类是否必定须要无参构造方法?为何?
0.2 反射的使用有什么优点和劣势?为何说反射能够下降耦合?
0.3 反射比较损耗性能,为何这样说?可否经过案例对比说明反射机制损耗性能……
0.4 反射是一种具备与类进行动态交互能力的一种机制,为何要强调动态交互呢?
0.5 Java反射中的setAccessible()方法是否破坏了类的访问规则
0.2 反射的使用有什么优点和劣势?
射的初衷不是方便你去建立一个对象,而是让你在写代码的时候能够更加灵活,下降耦合,提升代码的自适应能力。
0.4 反射是一种具备与类进行动态交互能力的一种机制,为何要强调动态交互呢
动态加载,也就是在运行的时候才会加载,而不是在编译的时候,在须要的时候才进行加载获取,或者说你能够在任什么时候候加载一个不存在的类到内存中,而后进行各类交互,或者获取一个没有公开的类的全部信息,换句话说,开发者能够随时随意的利用反射的这种机制动态进行一些特殊的事情。
1.1 反射概述
JAVA反射机制是在运行状态中,对于任意一个类,都可以知道这个类的全部属性和方法;
对于任意一个对象,都可以调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。
而解剖使用的就是Class类中的方法,因此先要获取到每个字节码文件对应的Class类型的对象
1.2 获取class文件对象的三种方式
1.2.1 这三种方式为:
a:Object类的getClass()方法
b:静态属性class
c:Class类中静态方法forName()
1.2.2 第一种方法【Object类的getClass()方法】
1.在内存中新建一个Person的实例,对象p对这个内存地址进行引用
2.对象p调用getClass()返回对象p所对应的Class对
3.调用newInstance()方法让Class对象在内存中建立对应的实例,而且让p2引用实例的内存地址
1.2.3 第二种方法【静态属性class】
1.获取指定类型的Class对象,这里是Person
2.调用newInstance()方法在让Class对象在内存中建立对应的实例,而且让p引用实例的内存地址
1.2.4 第三种方法【Class类中静态方法forName()】
1.经过JVM查找并加载指定的类(上面的代码指定加载了com.fanshe包中的Person类)
2.调用newInstance()方法让加载完的类在内存中建立对应的实例,并把实例赋值给p
注意:若是找不到时,它会抛出 ClassNotFoundException 这个异常,这个很好理解,由于若是查找的类没有在 JVM 中加载的话,天然要告诉开发者。
1.3 经过反射获取无参构造方法并使用
A:获取全部构造方法
public Constructor[] getConstructors()
public Constructor[] getDeclaredConstructors()
B:获取单个构造方法
public Constructor getConstructor(Class... parameterTypes)
public Constructor getDeclaredConstructor(Class... parameterTypes)
方法关键字
getDeclareMethods() 获取全部的方法
getReturnType() 获取方法的返回值类型
getParameterTypes() 获取方法的传入参数类型
getDeclareMethod("方法名,参数类型.class,....") 得到特定的方法
构造方法关键字
getDeclaredConstructors() 获取全部的构造方法
getDeclaredConstructors(参数类型.class,....) 获取特定的构造方法
成员变量
getDeclaredFields 获取全部成员变量
getDeclaredField(参数类型.class,....) 获取特定的成员变量
父类和父接口
getSuperclass() 获取某类的父类
getInterfaces() 获取某类实现的接口
1.4 反射的定义
JAVA反射机制是在运行状态中,对于任意一个类,都可以知道这个类的全部属性和方法;对于任意一个对象,都可以调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制
1.5 反射的组成
因为反射最终也必须有类参与,所以反射的组成通常有下面几个方面组成:
1.java.lang.Class.java:类对象;
2.java.lang.reflect.Constructor.java:类的构造器对象;
3.java.lang.reflect.Method.java:类的方法对象;
4.java.lang.reflect.Field.java:类的属性对象;
反射中类的加载过程
根据虚拟机的工做原理,通常状况下,类须要通过:加载->验证->准备->解析->初始化->使用->卸载这个过程,若是须要反射的类没有在内存中,那么首先会通过加载这个过程,并在在内存中生成一个class对象,有了这个class对象的引用,就能够发挥开发者的想象力,作本身想作的事情了。
1.6 反射的做用有哪些
前面只是说了反射是一种具备与Java类进行动态交互能力的一种机制,在Java和Android开发中,通常状况下下面几种场景会用到反射机制.
须要访问隐藏属性或者调用方法改变程序原来的逻辑,这个在开发中很常见的,因为一些缘由,系统并无开放一些接口出来,这个时候利用反射是一个有效的解决方法
自定义注解,注解就是在运行时利用反射机制来获取的。
在开发中动态加载类,好比在Android中的动态加载解决65k问题等等,模块化和插件化都离不开反射,离开了反射步履维艰。
2.1.4 经过反射获取成员变量[包含私有]并使用
2.1.5 经过反射获取无参无返回值成员方法[包含私有]并使用
2.1.6 经过反射获取带参无返回值成员方法并使用
2.1.7 经过反射获取带参带返回值成员方法并使用
3.1.1 设置.setAccessible(true)暴力访问权限
通常状况下,咱们并不能对类的私有字段进行操做,利用反射也不例外,但有的时候,例如要序列化的时候,咱们又必须有能力去处理这些字段,这时候,咱们就须要调用AccessibleObject上的setAccessible()方法来容许这种访问,而因为反射类中的Field,Method和Constructor继承自AccessibleObject,所以,经过在这些类上调用setAccessible()方法,咱们能够实现对这些字段的操做。
3.1.2 获取Filed两个方法的区别
二者的区别就是 getDeclaredField() 获取的是 Class 中被 private 修饰的属性。 getField() 方法获取的是非私有属性,而且 getField() 在当前 Class 获取不到时会向祖先类获取。
3.1.3 获取Field的类型
能够看到 getGenericType() 确实把泛型都打印出来了,它比 getType() 返回的内容更详细。
3.1.4 Method获取方法名,获取方法参数
3.1.5 Method方法的invoke()方法执行
Method 调用 invoke() 的时候,存在许多细节:
invoke() 方法中第一个参数 Object 实质上是 Method 所依附的 Class 对应的类的实例,若是这个方法是一个静态方法,那么 ojb 为 null,后面的可变参数 Object 对应的天然就是参数。
invoke() 返回的对象是 Object,因此实际上执行的时候要进行强制转换。
在对Method调用invoke()的时候,若是方法自己会抛出异常,那么这个异常就会通过包装,由Method统一抛InvocationTargetException。而经过InvocationTargetException.getCause() 能够获取真正的异常。
本文做者:潇湘剑雨
本文为云栖社区原创内容,未经容许不得转载。