从01开始 从01开始
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)

peterjxl

人生如逆旅,我亦是行人
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)
  • JavaSE

  • JavaSenior

    • 反射

      • 什么是反射
        • 引入反射之前
        • 什么是反射
      • 反射的原理
      • Class介绍
      • 反射小结
    • 注解

    • 集合类

    • Java
  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java并发

  • Java源码

  • JVM

  • 韩顺平

  • Java
  • Java
  • JavaSenior
  • 反射
2022-12-30
目录

什么是反射

# 00.什么是反射

‍

引入反射的概念之前,我们先看看为什么需要反射,用了有什么好处

  ‍

‍

# 引入反射之前

‍

反射之中包含了一个“反”的概念,所以要想解释反射就必须先从“正”开始解释。一般而言,当用户使用一个类的时候,应该先知道这个类,而后通过这个类产生实例化对象。--from MLDN李兴华老师

‍

我们创建一个对象,往往是使用先import,再使用的方式,例如

import java.util.HashMap;

//……省略其他代码
Map<Integer, Integer> map = new HashMap<>();
map.put(1, 1);
1
2
3
4
5

如果后续有需求,要改成LinkedHashMap​,那么就得改动代码

import java.util.LinkedHashMap;
//……省略其他代码
Map<Integer, Integer> map = new LinkedHashMap<>();
1
2
3

如果后续又有需求,要改成其他类,那么每有一个需求,都要重新改动一次……

‍

或许有人要问了,真有这样的需求吗?有的,例如JDBC里,我们连接数据库需要一个驱动类

class.forName("com.mysql.jdbc.Driver");

//获取与数据库连接的对象-Connetcion
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/learn", "root", "root");

//获取执行sql语句的statement对象
statement = connection.createStatement();

//执行sql语句,拿到结果集
resultSet = statement.executeQuery("SELECT * FROM users");
1
2
3
4
5
6
7
8
9
10

‍

‍

当更换数据库的时候,就得修改驱动类,换成其他数据库厂家的驱动类。改代码是麻烦的,需要重新编译和测试,常常是将这些需要频繁改动的地方,写到一个配置文件里,这样,我们就就不用修改代码了,而是通过修改配置的方式去实现变化。

有人可能会问:“那还是要改啊,我改代码也很快啊,你改配置不也是要改吗”。

其实不一样的,我举个例子:

  • 三歪写了一个JDBC组件,把各种配置都写死在代码上,比如上面的driver/username/数据库连接数等等。现在三歪不干了,要跑路了。
  • 敖丙来接手三歪的代码,敖丙刚开始接手项目,公司说要换数据库。敖丙给领导说:这玩意,我改改配置就好了,几分钟完事。
  • 敖丙找了半天都没找到配置的地方,由于三歪写的代码又臭又烂,找了半天才找到入口和对应的位置。
  • 改代码的风险要比改配置大,即便不知道代码的实现都能通过改配置来完成要做的事。

‍

修改为读取配置文件后,代码类似这样:

//获取配置文件的读入流
InputStream inputStream = UtilsDemo.class.getClassLoader().getResourceAsStream("db.properties");

Properties properties = new Properties();
properties.load(inputStream);

//获取配置文件的信息
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");

//加载驱动类
Class.forName(driver);
1
2
3
4
5
6
7
8
9
10
11
12
13
14

‍

也就是说,应用程序在编译的时候,是不知道到底使用的是什么类的,只要到了运行的时候,才会动态的把类加载进内存(参考第14行,就是加载类进来),并使用其方法,这通过正射是做不到的,也是反射的一个优点:解耦

‍

# 什么是反射

在Java中,反射(Reflection)是指程序在运行期可以拿到一个对象的所有信息。反射非常重要,没有反射,也就没有后面我们要学习的框架了

框架:半成品的代码。可以在框架的基础上进行软件开发,简化编码,这里不展开,后续我们学习Spring的时候,它就是通过反射实例化对象的:当程序启动时,Spring 会读取配置文件applicationContext.xml​​,并解析出里面所有的标签实例化到IOC​​容器中。

后面学习的日志框架也是一样的,Commons Logging总是优先使用Log4j,只有当Log4j不存在时,才使用JDK的logging。

‍

‍

反射的用处举例:其实,相信大部分读者都至少享受过反射带来的好处。例如在IDE中定义了一个字符串变量c​,当输入 c.​ 时,IDE会自动提示String类型的方法。这就是反射的一个应用:获取该类的方法。

String c = "abc";
c.toString();
1
2

‍

关于反射的一些专业的说法:在Gilad Bracha与David Ungar合作的论文是这样说的

Reflective language architectures may be characterized in terms of their support for:

  1. Introspection. The ability of a program to examine its own structure.
  2. Self-modification. The ability of a program to change its own structure.
  3. Execution of dynamically generated code. The ability to execute program fragments that are not statically known. This is a special case of 2.
  4. ​Intercession​. The ability to modify the semantics of the underlying programming language from within the language itself (the term intercession is sometimes used in a broader sense in parts of the literature, but we adopt the narrower definition of intercession given here, based on [18]).

完整论文:Mirrors: Design Principles for Meta-level Facilities of Object-Oriented Programming Languages (opens new window)

‍

‍

在GitHub上编辑此页 (opens new window)
上次更新: 2022/12/30 09:26:25
Java
反射的原理

← Java 反射的原理→

Theme by Vdoing | Copyright © 2022-2023 粤ICP备2022067627号-1 粤公网安备 44011302003646号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式