共计 2635 个字符,预计需要花费 7 分钟才能阅读完成。
反射十分弱小和有用,当初市面上绝大部分框架 (spring、mybatis、rocketmq 等等) 中都有反射的影子,反射机制在框架设计中占有无足轻重的作用。
所以,在你 Java 进阶的路线上,你须要把握好反射。
怎么能力学好反射,咱们须要弄懂以下几个问题:
1. 反射是什么?
2. 反射有什么用?
3. 反射的实现原理?
4. 怎么用反射?
上面我就针对以上的疑难,一一来解说。
反射是什么?
反射是 java 语言的一个个性,它允程序在运行时(留神不是编译的时候)来进行自我查看并且对外部的成员进行操作。
反射是在运行状态中,对于任意一个类,都可能晓得这个类的所有属性和办法, 对于任意一个对象,都可能调用它的任意办法和属性, 这种动静获取信息以及动静调用对象办法的性能称为 java 语言的反射机制。
一句话总结:反射就是在运行时才晓得要操作的类是什么,并且能够在运行时获取类的残缺结构,并调用对应的办法。
为什么要用反射?
Java Reflection 性能十分弱小,并且十分有用,比方:
- 获取任意类的名称、package 信息、所有属性、办法、注解、类型、类加载器等
- 获取任意对象的属性,并且能扭转对象的属性
- 调用任意对象的办法
- 判断任意一个对象所属的类
- 实例化任意一个类的对象
- 通过反射咱们能够实现动静拆卸,升高代码的耦合度, 动静代理等。
怎么应用反射?
个别状况下咱们通过反射创立类对象次要有两种形式:
通过 Class 对象的 newInstance() 办法
通过 Constructor 对象的 newInstance() 办法
第一种:通过 Class 对象的 newInstance() 办法。
Class clz = Class.forName("com.mikechen.reflection.JiaGou");
JiaGou jg= (JiaGou)clz.newInstance();
第二种:通过 Constructor 对象的 newInstance() 办法
Class clz = Class.forName("com.mikechen.reflection.JiaGou");
Constructor constructor = clz.getConstructor();
JiaGou jg= (JiaGou)constructor.newInstance();
通过 Constructor 对象创立类对象能够抉择特定构造方法,而通过 Class 对象则只能应用默认的无参数构造方法, 上面的代码就调用了一个有参数的构造方法进行了类对象的初始化。
Class clz = Class.forName("com.mikechen.reflection.JiaGou");
Constructor constructor = clz.getConstructor(String.class);
JiaGou jg= (JiaGou)constructor.newInstance("mikechen 的互联网架构");
接下来咱们就能够通过具体的 API 调用获取到具体的属性或者办法等具体了。
1、获取类的成员变量的信息
//mikechen 的互联网架构
Field[] fields = cls.getDeclaredFields();
更加具体成员变量获取参考如下:
2、取得类办法
//mikechen 的互联网架构
Method[] methods = cls.getDeclaredMethods();
更加具体办法获取参考如下:
3、取得构造函数
//mikechen 的互联网架构
Constructor[] constructors = cls.getDeclaredConstructors();
更加具体构造函数获取参考如下:
这样通过反射就能够做在运行时获取类的残缺结构,并取得类信息了。
通过以上一个小案例理解了反射的应用,但如果你想对反射把握得更好,还需深刻了解反射背地的底层实现原理。
反射工作原理?
调用反射的总体流程如下:
1、当咱们编写完一个 Java 我的项目之后,每个 java 文件都会被编译成一个.class 文件。
2、这些 class 文件在程序运行时会被 ClassLoader 加载到 JVM 中,当一个类被加载当前,JVM 就会在内存中主动产生一个 Class 对象。
3、通过 Class 对象获取 Field/Method/Construcor
咱们个别平时是通过 new 的模式创建对象实际上就是通过这些 Class 来创立的,只不过这个 class 文件是编译的时候就生成的,程序相当于写死了给 jvm 去跑。
反射是什么呢?当咱们的程序在运行时,须要动静的加载一些类这些类可能之前用不到所以不必加载到 jvm,而是在运行时依据须要才加载。
原来应用 new 的时候,须要明确的指定类名,这个时候属于硬编码实现,而在应用反射的时候,能够只传入类名参数,就能够生成对象,升高了耦合性,使得程序更具灵活性。
反射的利用场景
举个例子咱们的我的项目底层数据库有时是用 mysql,有时用 oracle,须要动静地依据理论状况加载驱动类,这个时候反射就有用了,假如 com.mikechen.java.myqlConnection,com.mikechen.java.oracleConnection 这两个类咱们要用。
这时候咱们在应用 JDBC 连贯数据库时应用 Class.forName()通过反射加载数据库的驱动程序,如果是 mysql 则传入 mysql 的驱动类,而如果是 oracle 则传入的参数就变成另一个了。
Spring 框架的 IOC(动静加载治理 Bean),Spring 通过配置文件配置各种各样的 bean,你须要用到哪些 bean 就配哪些,spring 容器就会依据你的需要去动静加载,你的程序就能强壮地运行。
还有 Spring AOP(动静代理)性能都和反射有关系。
除此之外还有很多框架:mybatis、dubbo、rocketmq 等等都会用到反射机制。
以上!
对于作者:mikechen,10+ 年大厂架构教训,曾任职阿里、淘宝、百度,分享十余年 BAT 架构教训以及面试心得!
关注集体公众号:mikechen 的互联网架构,第一工夫获取最新 BAT 架构技术干货分享!
公众号后盾回复 架构,还能够获取我独家秘制 Java 大厂架构干货视频噢。
近期●必看热文
1、史上最全阿里 Java 面试题库(2022 最新版)
2、2022 金三银四一线大厂必考题答案解析合集
3、Java 多线程与并发系列从 0 到 1 全副合集
4、JVM(Java 虚拟机)从 0 到 1 全副合集
5、单点登录 SSO 的实现原理与计划详解
6、史上最强音讯队列 MQ 万字图文总结!