1、引言

反射的重点在于这个“反”字,理解反射,重点要在于这个“反”的含义。既然是“反”,那么一定是与通常不一致的情况。那我们首先来看下正常情况下,Java程序从编写到运行的一个过程。

在Java中,万物皆是类。开发人员在编写Java代码时,就是一个创建并编写大量Java类的过程。Java程序运行时,ClassLoader就会将所有用到的Java类加载到JVM虚拟机中。如下是一个简单的Java示例代码,代码中定义了一个Person类,以及一个包含main函数作为程序入口的Main类 。在main函数里面,代码引用了Person类。

class Person {private String name;public Person() {}public Person(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}class Main {public static void main(String[] args) {Person person = new Person("Joy");System.out.println(person.getName());}
}

这个小程序,从开发者层面来看,在开发这段小程序时,开发人员一定是知道main程序中依赖的Person类的详细信息,包括Person类的属性、方法等,所以开发人员可以在main函数中明确的使用Person这个类。

从代码的编译层面来看,在这个小程序的编译阶段,编译Main这个类时,编译器发现了对Person类的引用,那么编译器就一定会去找Person类的相关信息,然后将Person类进行编译,以便在Main类中可以正常使用。编译器如果没有找到Person类,那么就一定会编译失败。换言之,这个小程序编译成功了,那么就说明在编译阶段,编译器已经获取到了所有Person类的详细信息。

从代码的运行程序面来看,程序运行时,ClassLoader将需要用到的类都加载到了JVM中,所有JVM中也一定是清楚的知道相关类的所有信息的。

如下图所示,对于一个类来说,从代码编写阶段到程序运行阶段,主要有以下几个状态:

首先一个类对应的是*.java文件中的一个class,java文件中定义了类的各种属性、方法等。经过编译之后,每个类对应一个class文件,class文件中也描述了类的所有相关信息。程序运行时,类加载器对class文件进行解析,加载对应的类,同时会在JVM中生成一个Class对象,每个Class对象和每个class文件是一一对应的,也就是每个类在JVM中都有且只有一个对应的Class对象存在。这个Class对象描述了其对应的java类的详细信息。当要实例化这个类的一个对象时,就是根据这个类对应的Class对象获取类的相关信息,并根据此信息生成该类的一个新的对象。

以上就是java程序中,在通常情况下运行时,类从代码阶段到执行阶段所有的几个简单状态。

2、什么是反射

说完通常情况了,就该说一下特殊情况了。假设有这么一个需求,要求编写一段代码,这个代码的作用是,对于给定的任意一个类,要求调用这个类的任意某个方法。

这个要怎么做呢?

和上面的不同点在于,在开发人员层面,编写上面示例代码时,开发者是明确知道Person类的,知道Person类的所有信息,也知道要调用Person类的某个具体的方法。但是现在这个需求,开发人员什么都不知道了,不知道到底要调用类的哪个方法了,甚至不知道到底要调用哪个类的方法,对于这个类的信息是一无所知,只知道在程序运行期间会给你一个类。

从编译层面来看,在编译阶段,是没有这个类的信息的,编译器也是对这个类一无所知的。这个类的信息是在运行阶段才会有的。

那么就没有办法完成了吗?办法当然是有的,就算是开发人员在开发时不知道这个类是啥,就算是编译器在编译阶段不知道这个类的信息,但是在程序的运行阶段,是可以想办法获取这个类的信息的。只要在程序的运行阶段,我们获取了这个类的所有信息,那么我们想干啥就干啥,想执行它的啥方法就可以执行它的啥方法了。这就是反射。换言之,反射就是在程序的运行期动态获取类的信息。

如下图所示,虽然在代码开发和编译阶段可能不知道某个类的详细信息,但是在运行阶段,当这个类被加载到JVM中了就会生成一个Class对象,我们通过这个Class对象,在运行期一样可以获得这个类对应的信息,这就是反射。

这里可能就有疑问了,JVM中的Class对象是由class文件加载后生成的,为什么一定要等到加载之后才能获取类的信息呢?加载之前,从class文件中不也能够获取到这个类的信息吗?

的确,如果在程序运行之前,就拥有这个类的class文件,比如是开发人员自己写的代码编译出的class文件,或者是引用别人的jar包里面的class文件,都是可以提前获取到类的信息的,也就不用反射了。但问题是,在程序运行之前,并不是都有对应的class文件的,可能这个class文件是程序在运行时才从网络中获取到的字节流呢?甚至这个class文件就是在程序运行期才动态生成的字节流呢?这些情况下提前是不可能获知到类的相关信息的,就只能通过反射在运行期动态获取类的信息了。

下面就是一个反射的小例子,实现了上面所说的功能:

对于给定的任意一个类,要求调用这个类的任意某个方法。

import java.lang.reflect.Method;class Person {private String name;public Person() {}public Person(String name) {this.name = name;}public String getName() {System.out.println("==========get name executed!==========");return name;}public void setName(String name) {this.name = name;}
}class Main {public static void main(String[] args) throws Exception {String className = args[0];String methodName = args[1];Class cls = Class.forName(className);Method m = cls.getMethod(methodName);Object o = cls.newInstance();m.invoke(o);}
}

程序的执行结果:程序运行时,指定执行Person类的getName方法。

3、反射的用途

通过前面的叙述,就算是开发人员在开发代码时可以不知道某些类的相关信息,编译器在编译阶段也可以不知道类的相关信息,但是通过在运行期动态获取类的相关信息,依然可以完成许多事情。许多的Java框架比如Spring、mybatis等等,都是基于反射实现的。

总之,最重要的就是要理解一点,对于java类,通常情况下是开发人员自己编写的java文件通过编译得到对应的class文件,或者直接引用别人的jar包得到对应的class文件,在这些方式里面,程序在运行之前就已经获取到类对应的信息了,就无需用到反射。

而反射的作用场景就在于,在程序运行之前,是获取不到对应的class文件的。这些class文件有可能是程序运行中从其他地方获取到的,有可能是动态生成的。在这种情况下,就需要通过反射在运行期来动态获取对应类的相关信息。

4、再次理解Class类

在Java语言当中,一切都是类与对象。

比如说有三辆具体的车,每一辆车都有各自的属性(比如颜色)和相同方法(比如前进),我们可以抽象出来车这样一个类,三辆车中的每一辆都是车这个类的一个对象(实例)。

在生活中,既可以有车这个类,还可以有人这个类,也可以有树这个类,总之,我们可以有无穷多个类。那么其实我们可以站在更高的一个角度来看待问题,把各个类都抽象出来形成一个新的类别,这个类别名字就叫作“类”(Class),就像我们可以把几辆车抽象出来形成的一个类叫“车”一样。车这个类是抽象出来的新的“类”的一个实例,人这个类也是抽象出来的新的这个“类”的一个实例。

为了形象化一点,我们可以这样假想以便于理解:对于每一个类,比如车这个类Car,会有对应的Car.class,我们具有无数个类也就具有无数个class文件。想象一下其实每个class文件都是一个对象,一个叫做“类”的这个类的对象。

总而言之:车对应的类型是Car,可以有无数辆具体的车,但只会有一个Car类别;类对应的类型是Class类,可以有无数个具体的类(对应无数个class文件),但只会有一个Class类别。

反射一、反射的基本概念相关推荐

  1. Java反射机制的基本概念与使用_Java进阶之reflection(反射机制)——反射概念与基础...

    反射机制是Java动态性之一,而说到动态性首先得了解动态语言.那么何为动态语言? 一.动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见 ...

  2. 二、什么是反射、反射可以做些什么

    什么是反射,反射能干嘛? 反射是:指程序可以访问.检测和修改它本身状态或行为的一种能力 反射是一种能力,所以给的定义就是说明了它能干嘛. 我们平时用反射主要做: 获取类型的相关信息 动态调用方法 动态 ...

  3. 什么是反射、反射可以做些什么

    阅读目录 什么是反射,反射能干嘛? 获取类型的相关信息 获取类型本身信息(命名空间名.全名.是否是抽象.是否是类..... 获取类型成员信息(通过Tyep中的方法GetMembers) 动态调用方法 ...

  4. 什么是反射,反射能干嘛?

    原文链接:农码一生 反射是:指程序可以访问.检测和修改它本身状态或行为的一种能力. 反射是一种能力,所以给的定义就是说明了它能干嘛. 我们平时用反射主要做: 1.获取类型的相关信息 2.动态调用方法 ...

  5. Java中为什么需要反射?反射要解决什么问题?

    Java中为什么需要反射?反射要解决什么问题? 参考文章: (1)Java中为什么需要反射?反射要解决什么问题? (2)https://www.cnblogs.com/buoge/p/9285142. ...

  6. 反射:通过反射获取成员变量并使用

    首先建一个实体类,用于数据访问 package star.july.entity;public class Student {private String name;int age;public St ...

  7. java 反射应用_java反射(二)--反射应用案例

    一.反射实例化对象 经过一系列的分析之后发现虽然可以获取Class类的实例化对象,但是依然觉得这个对象的获取意义不是很大,因此可以通过以下几个案例去理解反射的核心意义 --反射实例化对象:获取Clas ...

  8. 依赖注入底层反射原理_Spring中反射与反射的原理(转载)

    Spring 中的反射与反射的原理 | Depp Wang's Blog 在造轮子:实现一个简易的 Spring IoC 容器一文中提到 Spring 在创建 Bean 实例和依赖注入时使用了反射,本 ...

  9. 『设计模式』反射,反射程序员的快乐!为什么我老是加班?为什么我工资不如他多?原来是我不懂反射!

    23种设计模式+额外常用设计模式汇总 (持续更新) Java是一门准动态语言,是因为存在反射机制,如果你不会是不是就等于白学了? 看完不会,请评论,我亲自给你解释,嘻嘻! 什么是动态语言? 动态语言, ...

  10. 【重难点】【Java基础 05】说一说你平时遇到的异常、什么情景下会用到反射、反射的底层原理

    [重难点][Java基础 05]说一说你平时遇到的异常.什么情景下会用到反射.反射的底层原理 文章目录 [重难点][Java基础 05]说一说你平时遇到的异常.什么情景下会用到反射.反射的底层原理 一 ...

最新文章

  1. BeautifulSoup中的.text方法和get_text()方法的区别
  2. 记录工作中第一次解决bug的小事
  3. Deep Learning Toolkits 的比较(转)
  4. JDK源码——利用模板方法看设计模式
  5. 框架中的Blob数据的定义
  6. Win10 Redstone再添新技能:深度集成App-V应用虚拟化
  7. python自动化办公教程百度云-用Python自动办公,做职场高手,16章完整版百度云盘...
  8. Java之父:Solaris前景堪忧
  9. C语言--冒泡排序法(详细注释)
  10. python语言程序设计实践教程实验八答案_Python程序设计实践教程
  11. 【资料】《模拟电子技术基础-童诗白第四版》
  12. SQL Server中查询ORACLE的数据
  13. 什么软件测试情侣头像,扫图查情侣头像软件
  14. GIT 密钥生成工具puttygen使用技巧
  15. linux redhat下载地址
  16. 苹果笔记本电脑怎么编辑html,苹果笔记本电脑怎么操作 苹果笔记本电脑操作方法【详解】...
  17. python 模拟键盘鼠标输入_Python模拟键盘输入和鼠标操作
  18. 网站访问全过程涉及的网络协议详解
  19. Linux服务器搭建相关教程链接整理
  20. python:批量处理txt文件,读取txt文件内容,根据内容(例子为数字1)提取出对应txt文件到其他文件夹,后根据txt文件名提取对应名字图片。

热门文章

  1. C语言基础入门48篇_13_关系运算符与关系表达式(等于(==)、不等于(叹=)、大于(>)、小于(<)、小于等于(<=)、大于等于(>=),5==nValue方式避免bug,==不可比较浮点型数据)
  2. 初识linux网络编程
  3. Android launcher 桌面抽屉切换动画
  4. unturned服务器重置,服务器配置文件Config.json说明
  5. iText7 学习笔记2--页眉页脚
  6. LNK2019解决思路
  7. 【数据结构】初识时间空间复杂度
  8. AWS KVS(Kinesis Video Streams)之WebRTC移植编译(三)
  9. 达人秀计算机教学,回顾〡信息技术达人秀
  10. 关于linux的考试题