Java中的反射机制
一、什么是反射
反射,顾名思义,应该是某个操作的逆向过程。java的反射机制,指代创建对象的逆向过程。
【创建对象的过程】
通过类型,来创建该类型的实例
【反射的过程】
通过实例,来获取该实例的类型
反射:获取要创建实例的类型信息的过程
【注】java语言是静态语言,反射机制让java有了动态语言的特性
简单粗暴来说,静态语言指编译时检查数据类型的语言,定义变量时必须指定变量的类型;动态语言指运行时才检查数据类型的语言,定义变量时不需要指定变量类型
二、反射有哪些特性
【反射能干啥】
- 最基本的,可以通过实例来获取实例类型
- 让权限修饰符形同虚设,直白说,就是你私有化的东西我想用就用,想怎么用就怎么用
- 可以动态创建对象、动态调用方法、动态设置属性
【提问】
1)我私有的东西你想用就用,你破坏了封装性,反射的存在是java的漏洞吧?
答:大佬们不是傻子,这么明显的低级错误能让它存在这么长时间,所以我们需要换一个角度想这个问题。我们需要考虑的是,封装存在的目的和反射存在的目的是什么,而不是它们的功能为什么矛盾。
- 封装:是为了提供一组完备的、独立的功能,暴露出方便使用的API,隐藏复杂的实现逻辑。权限修饰符的作用是提示哪些内容调用者不需要知道,哪些可以放心大胆的使用。
- 反射:是为了解决在编译时无法确定创建实例类型的问题
所以,已经告诉你,我私有的你不需要使用,就可以轻松达成你的目的,你非要用,想给自己找麻烦,臣妾也无能为力了
三、反射的使用
1、引包:反射相关类所在包
- java.lang.Class:是表示类型的一个抽象,即表示类型的类.反射就是为了获取一个Class实例,一个Class实例就是一个运行时类(以一定数据格式存储在内存中的类)
- Class的实例可以是啥
- 类
- 接口
- 注解
- 数组:类型和维度相同的数组Class实例相同
- 枚举
- 基本类型
- void
- Class的实例可以是啥
- java.lang.reflect.*
- Constructor:表示构造器的类
- Method:表示方法的类
- Field:表示属性的类
- …
2、获取类型
- 通过类的class属性
Class clazz=类名.class
- 通过对象的getClass方法
Class clazz=对象名.getClass()
- 通过类的全路径名(包名.类名)
- 通过Class类静态方法
Class clazz=Class.forName(全路径名)
- 通过类加载器
ClassLoader loader=当前类.class.getClassLoader(); Class clazz=loader.loadClass(全路径名)
- 通过Class类静态方法
3、创建实例
- 通过Class实例的newInstance方法
clazz.newInstance()
- 要求:
- 类有空参构造器
- 权限为public
- 要求:
- 使用构造器对象
构造器对象.newInstance()
4、调用方法/属性
- 获取方法
clazz.getDeclaredMethod("方法名")
- 调用方法
method.invoke(对象名,参数)
- 获取属性
clazz.getDeclaredField("属性名")
- 设置属性值
field.set(clazz创建的实例,设置属性的值)
- 让私有成员可使用
field/method.setAccessible(true)