反射非常强大和有用,现在市面上绝大部分框架(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. 【译】使用 Visual Studio 调试外部源代码

    您是否曾经需要调试并进入依赖于 NuGet 或 .NET 库的代码,而这些库并没有构建为您的解决方案的一部分? 现在,调试它们并不像调试作为解决方案一部分的项目那么容易.从 Visual Studio ...

  2. CSAcademy Prefix Suffix Counting 题解

    CSAcademy Prefix Suffix Counting 题解 目录 CSAcademy Prefix Suffix Counting 题解 题意 思路 做法 程序 题意 给你两个数字\(N\ ...

  3. android studio出现 Could not initialize class com.android.sdklib.repository.AndroidSdkHandler

    新的android studio  (4.2)已经不支持旧有的 com.android.tools.build:gradle:2.3.3 了,有些方法和类会找不到. 去build.gradle中把这个 ...

  4. NOAA数据下载方法

    NOAA OneStop https://data.noaa.gov/onestop/about NOAA 数据搜索平台,在一个地方同时搜索NOAA的 Geophysical, oceans, coa ...

  5. Kali渗透安卓手机

    kali渗透安卓手机 1.生成木马文件 msfvenom -p android/meterpreter/reverse_tcp LHOST=ip LPORT=端口 R > test.apk 在终 ...

  6. CF1036A Function Height 题解

    Content 给定一个坐标系,在它的 \(x\) 轴上有 \(2n+1\) 个点 \(P_0,P_1,P_2,...,P_{2n}\),其中对于 \(0\leqslant i\leqslant 2n ...

  7. Linux使用tar解压的时候去掉父级目录

    去除解压目录结构使用  --strip-components N 如: 压缩文件text.tar 中文件信息为 src/src1/src2/text.txt 运行 tar -zxvf text.tar ...

  8. SpringBoot简单整合Gateway网关

    引入依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>s ...

  9. Spring Tool Suite(STS)基本安装配置

    下载jar包:https://spring.io/tools 下载完成后 打开所在文件夹 执行命令行 jar -jar  下载的jar包文件名 然后会自动解压 双击打开软件 配置主面板窗口 配置好之后 ...

  10. 【linux项目】lichee nano linux烧写

    目录 前言 参考: 安装交叉编译链 搭建 SPI FLASH 烧录环境 让芯片进入烧写模式 sunxi 烧写命令 u-boot 裁剪 拉取 u-boot 源码 配置 u-boot 检查 flash 驱 ...