反射非常强大和有用,现在市面上绝大部分框架(spring、mybatis、rocketmq等等)中都有反射的影子,反射机制在框架设计中占有举足轻重的作用。

所以,在你Java进阶的道路上,你需要掌握好反射。

怎么才能学好反射,我们需要弄懂以下几个问题:

1.反射是什么?

2.反射有什么用?

3.反射的实现原理?

4.怎么用反射?

下面我就针对以上的疑问,一一来讲解。

反射是什么?

反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。

反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意方法和属性,这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

一句话总结:反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。

为什么要用反射?

Java Reflection功能非常强大,并且非常有用,比如:

  • 获取任意类的名称、package信息、所有属性、方法、注解、类型、类加载器等
  • 获取任意对象的属性,并且能改变对象的属性
  • 调用任意对象的方法
  • 判断任意一个对象所属的类
  • 实例化任意一个类的对象
  • 通过反射我们可以实现动态装配,降低代码的耦合度,动态代理等。

怎么使用反射?

一般情况下我们通过反射创建类对象主要有两种方式:

  • 通过 Class 对象的 newInstance() 方法
  • 通过 Constructor 对象的 newInstance() 方法

第一种:通过 Class 对象的 newInstance() 方法。

  1. Class clz = Class.forName("com.mikechen.reflection.JiaGou");
  2. JiaGou jg= (JiaGou)clz.newInstance();

第二种:通过 Constructor 对象的 newInstance() 方法

  1. Class clz = Class.forName("com.mikechen.reflection.JiaGou");
  2. Constructor constructor = clz.getConstructor();
  3. JiaGou jg= (JiaGou)constructor.newInstance();

通过 Constructor 对象创建类对象可以选择特定构造方法,而通过 Class 对象则只能使用默认的无参数构造方法,下面的代码就调用了一个有参数的构造方法进行了类对象的初始化。

  1. Class clz = Class.forName("com.mikechen.reflection.JiaGou");
  2. Constructor constructor = clz.getConstructor(String.class);
  3. JiaGou jg= (JiaGou)constructor.newInstance("mikechen的互联网架构");

接下来我们就可以通过具体的API调用获取到详细的属性或者方法等详细了。

1、获取类的成员变量的信息

  1. //mikechen的互联网架构
  2. Field[] fields = cls.getDeclaredFields();

更加详细成员变量获取参考如下:

2、获得类方法

  1. //mikechen的互联网架构
  2. Method[] methods = cls.getDeclaredMethods();

更加详细方法获取参考如下:

3、获得构造函数

  1. //mikechen的互联网架构
  2. 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, 资深技术专家,曾任职阿里、淘宝、百度,分享十余年BAT架构经验以及面试心得!
 
关注个人公众号:mikechen的互联网架构,第一时间获取最新BAT架构技术干货与面试经验分享!
 
公众号后台回复 架构,还可以获取我独家秘制Java大厂架构干货视频噢。

Java反射详解:入门+使用+原理+应用场景的更多相关文章

  1. java 反射详解

    反射的概念和原理 类字节码文件是在硬盘上存储的,是一个个的.class文件.我们在new一个对象时,JVM会先把字节码文件的信息读出来放到内存中,第二次用时,就不用在加载了,而是直接使用之前缓存的这个 ...

  2. java反射 详解!!!!

    java反射(特别通俗易懂) 反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一.反射的概述 JAVA反射机制是在运行状态 ...

  3. Java 反射详解 转载

    java 反射 定义 功能 示例 概要: Java反射机制详解 | |目录 1反射机制是什么 2反射机制能做什么 3反射机制的相关API ·通过一个对象获得完整的包名和类名 ·实例化Class类对象 ...

  4. java反射详解及说明

    首先写一个Person类: package lltse.base.reflectdemo; public class Person { private String name ="张三&qu ...

  5. 【转载】Java 反射详解

    目录 1.什么是反射? 2.反射能做什么? 3.反射的具体实现 4.根据反射获取父类属性 4.反射总结 反射反射,程序员的快乐! 1.什么是反射? Java反射就是在运行状态中,对于任意一个类,都能够 ...

  6. 《Java基础知识》Java 反射详解

    定义 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射 ...

  7. Java反射详解及应用示例

    反射是Java中最重要的内容之一,了解反射原理对我们学习各种框架具有很大的帮助 反射的原理: 反射应用示例: import java.lang.reflect.Constructor; import ...

  8. java反射详解

    本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象 ...

  9. java反射详解(转)

    本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象 ...

随机推荐

  1. KubeCon 2021|使用 eBPF 代替 iptables 优化服务网格数据面性能

    作者 刘旭,腾讯云高级工程师,专注容器云原生领域,有多年大规模 Kubernetes 集群管理及微服务治理经验,现负责腾讯云服务网格 TCM 数据面产品架构设计和研发工作. 引言 目前以 Istio[ ...

  2. CF157A Game Outcome 题解

    Content 有一个 \(n\times n\) 的矩阵,每个元素都有一个权值.求所有满足其所在纵列所有元素权值和大于其所在横列所有元素权值和的元素个数. 数据范围:\(1\leqslant n\l ...

  3. 【LeetCode】946. Validate Stack Sequences 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 模拟过程 日期 题目地址:https://leetc ...

  4. 【嵌入式】arduino IDE串口监视器可以正常使用但其他软件发送串口指令没有反应的问题

    解决办法: 1.检查 波特率baudrate 是否一致 2.检查 数据位长度databits 是否一致 3.检查 停止位长度stopbits 是否一致 4.检查 奇偶校验位 是否一致 5.(特殊)是否 ...

  5. 【感悟】观《BBC彩色二战纪录片》有感

    2020年7月2日到3日我看了纪录片,以下是我的一些感悟 1.作为进攻者,无论大事还是小事都需要一鼓作气做完,以免留给对手喘息的机会.(指:未消灭) 2.作为防守者,要有顽强抵抗的精神,但要保留撤退的 ...

  6. Jmeter环境变量配置你不得不知道的事情

    在安装Jmeter的过程中大家肯定需要配置环境,但是为什么要配置JDK的环境变量呢?大家有没有好奇过,有没有仔细去像一下呢,其实在安装Jmeter前,大家应该都知道Jmeter是我们JAVA开发的,J ...

  7. IT6516DP转VGA转换器|替代台湾联阳IT6516方案|CS5212Capstone

    台湾联阳IT6516是一种高性能的DP显示端口到VGA转换器方案芯片.IT6516结合DisplayPort接收器和三重DAC,通过转换功能支持DisplayPort输入和VGA输出.内置Displa ...

  8. Java初学者作业——声明变量对个人信息进行输入和输出

    返回本章节 返回作业目录 需求说明: 声明变量存储个人信息(姓名.年龄.性别.地址以及余额),通过键盘输入个人信息并存储在相应的变量中, 最后将个人信息输出. 实现思路: 声明存储姓名.年龄.性别.地 ...

  9. 编写Java程序,在子类老虎中重写父类动物的吃食方法

    返回本章节 返回作业目录 需求说明: 在子类老虎中重写父类动物的吃食方法 实现思路: 在子类老虎中重写父类动物的吃食方法的实现思路如下: 创建各种动物的父类Animal类,在该类中定义eat()方法. ...

  10. 编写Java程序,创建Dota游戏中的兵营类,兵营类有一个类成员变量count、一个实例变量name和另一个实例变量selfCount。

    返回本章节 返回作业目录 需求说明: 创建Dota游戏中的兵营类 兵营类有一个类成员变量count.一个实例变量name和另一个实例变量selfCount. count表示的是兵营已经创建士兵的总数: ...