Java—反射

什么是反射

反射就是把Java类中的各个成分映射成一个个的Java对象。

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

 优/缺点

1.可以在运行程序过程中,操作这些对象

2.可以降低耦合度,提高程序的可拓展性

1.反射很强大,但是消耗性能,主要是为了做工具和框架使用的

反射机制的功能

Java反射机制主要提供了以下功能:

  • 在运行时判断任意一个对象所属的类。
  • 在运行时构造任意一个类的对象。
  • 在运行时判断任意一个类所具有的成员变量和方法。
  • 在运行时调用任意一个对象的方法。
  • 生成动态代理。  

实现反射机制的类

Java中主要由以下的类来实现Java反射机制(这些类都位于java.lang.reflect包中):

  • Class类:代表一个类。 Field类:代表类的成员变量(成员变量也称为类的属性)。
  • Method类:代表类的方法。
  • Constructor类:代表类的构造方法。
  • Array类:提供了动态创建数组,以及访问数组的元素的静态方法。

反射的基本原理

一说到基本原理,有些同学可能就会觉得有些头痛,坦率地说,如果真要从源头说起的话,可能需要从 JVM 的类加载机制对象的创建过程说起,但这两点稍微展开一说,都需要很长的篇幅,而这不是本文的重点。所以,此处大家只需要知道有这样一个过程就好了,JVM 类加载、对象创建大概过程简化如下:(实际过程复杂的多,此处简化细节便于理解反射,以 User 对象为例)

1、将User.java源码编译成User.class二进制字节码文件;

  • 2、JVM 将User.class二进制字节码文件加载到 JVM 内存中,并生成 User 对应的唯一java.lang.Class对象; (任意实际对象,JVM 类加载器加载时都会创建其对应的唯一的 1 个 Class 对象)

  • 3、当我们通过 User user = new User(); 这种方式创建一个 User 对象时,JVM 就会通过 User 对象对应的java.lang.Class对象来实例化一个 User 对象;(JVM 通过new这个关键字,为我们“屏蔽”了类的加载检测、加载、初始化等过程,从而使我们实例化一个对象变得非常容易)

  • 4、反射,则是 JDK 为我们提供了几个基础核心类,让我们可以通过 API 的方式直接去加载 JVM 内存中相关类的 Class 对象,从而可以获取类的构造函数、方法、属性等,并实例化对象。(如果 JVM 内存中已经存在了实例化的对象,通过反射的方式,则可以修改该对象的属性和方法内容等)

JDK 中,关于反射相关操作的类、方法众多,笔者此处对其中核心的类、方法简单说明:

1、java.lang.Class

表示类的实体,在运行中的 Java 应用程序中表示类和接口。获取一个类的 Class 对象,通常有如下 3 种方式:

// 1、通过已存在的对象的getClass()方法获取
User user = new User();
Class clazz1 = user.getClass();
// 2、通过类的静态属性 class 获取
Class clazz2 = User.class;
// 3、通过java.lang.Class类的静态方法 Class.forName(“全限定名”)获取 (最常用,即上文笔者用的方式)
Class clazz3 = Class.forName("com.xiaojiang.demo.reflect.User");

当获取到 java.lang.Class 对象后,就可以通过相应 API 获取对象的构造函数、方法、属性、访问修饰符等信息,根据这些信息就可以实例化一个对象,并对其进行相关操作。

2、 java.lang.reflect.Constructor

表示类的构造函数(构造方法)

Constructor constructor = clazz.getConstructor();

3、java.lang.reflect.Method

表示类的方法。

Method method = clazz.getDeclaredMethod("doSomethingByName",String.class);

4、java.lang.reflect.Field

表示类的属性。

Field field = clazz.getDeclaredField("name");

5、java.lang.reflect.Modifier

用于判断类、方法、属性的访问修饰符,如privatepublic

Modifier.isPublic(method.getModifiers());

通过反射方式创建对象、调用对象的方法、属性有了进一步的理解,此处简单说明如下:

反射的应用场景

以下列出几项利用了 Java 反射机制的应用场景:

  1. 动态代理实现;

  2. 自定义注解;

  3. 序列化与反序列化;

  4. JDBC 实现;

  5. Spring 的 IOC、AOP;

小结

1、Java 反射特性的存在,是 Java 语言被认为是半动态语言的重要原因之一。因为反射机制的存在,我们可以灵活地实现很多功能。

2、JDK 提供了一个功能丰富的反射库工具集(java.lang.reflect包下),通过该工具集,我们可以方便地操作反射相关的功能。

3、反射的真正运用,远比本文示例中的复杂,如 Modifier 类,本文仅从基础的角度帮助理解大概流程。

4、如果需要深入理解反射机制,需要知道 JVM 类加载机制以及 Java 类的创建过程,有兴趣的可以去了解相关知识。

5、日常工作中,如果不是写底层框架相关代码的话,直接写反射代码的情况不会很多,但是几乎所有的 Java 技术栈相关的框架都有用到反射,所以,理解反射的基本原理,有利于我们理解整个 Java 技术栈相关技术的运行原理,可以说是刚需。

6、需要注意 Java 中对象和实例的区别,如:User 是一个用户对象,但不是实例,因为其只是一个抽象的概念,不表示某一个具体存在的实体,User 实例化的 xiaojiang 这个用户才是一个具体的实体。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扶小一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值