百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

又被问到了, java 面试题:反射的实现原理及用途?

ztj100 2025-08-05 22:25 4 浏览 0 评论


一、反射的实现原理

反射(Reflection)是 Java 在运行时动态获取类的元数据(如方法、字段、构造器等)并操作类对象的能力。其核心依赖于 JVM 的类加载机制java.lang.reflect 包中的关键类。

1. 核心实现机制

  • Class 对象:每个类被 JVM 加载时,都会生成一个唯一的 Class 对象,存储该类的元数据(方法、字段、构造器等)。
  • 类加载过程
  • 加载:类加载器(ClassLoader)将 .class 文件读入内存,生成 Class 对象。
  • 连接:验证字节码、分配静态变量内存、解析符号引用。
  • 初始化:执行静态代码块和静态变量赋值。
  • 反射入口:通过以下方式获取 Class 对象:
  • java
  • Class<?> clazz1 = Class.forName("全限定类名"); // 动态加载类 Class<?> clazz2 = 对象.getClass(); // 通过对象实例获取 Class<?> clazz3 = 类名.class; // 直接通过类名获取

2. 反射 API 核心类

  • Field:类的字段信息(如名称、类型、修饰符)。
  • Method:类的方法信息(如参数、返回值、注解)。
  • Constructor:类的构造方法信息。
  • Modifier:解析修饰符(如 public、private)。

3. 反射调用流程

java

// 获取 Class 对象
Class<?> clazz = Class.forName("com.example.User");

// 创建实例(调用无参构造)
Object obj = clazz.getDeclaredConstructor().newInstance();

// 获取私有字段并修改值
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);  // 关闭访问检查(突破封装性)
field.set(obj, "Tom");

// 调用方法
Method method = clazz.getMethod("setName", String.class);
method.invoke(obj, "Jerry");

二、反射的用途

反射在 Java 开发中常用于以下场景:

1. 动态加载与操作类

  • 框架开发:Spring 的依赖注入(DI)、MyBatis 的 ORM 映射。
  • 动态代理:JDK 动态代理(如 Proxy.newProxyInstance())基于反射生成代理类。
  • 注解处理:通过反射解析类/方法上的注解(如 JUnit 的 @Test)。

2. 通用工具开发

  • 序列化/反序列化:Jackson/GSON 通过反射获取字段信息生成 JSON。
  • 代码生成器:根据反射信息生成代码(如 MyBatis Generator)。

3. 突破访问限制

  • 访问私有成员:通过 setAccessible(true) 修改私有字段或调用私有方法。
  • java
  • // 调用私有方法 Method privateMethod = clazz.getDeclaredMethod("privateMethod"); privateMethod.setAccessible(true); privateMethod.invoke(obj);

4. 插件化与模块化

  • 动态加载类:通过 ClassLoader 加载外部 JAR 中的类(如插件系统)。

三、反射的优缺点

优点

缺点

灵活性高,支持动态操作类、方法、字段。

性能开销大:反射调用比直接调用慢 10~100 倍。

适合框架开发(如 Spring、Hibernate)。

破坏封装性:可访问私有成员,导致安全隐患。

支持运行时动态加载类(如热部署)。

代码复杂度高:反射代码可读性差,调试困难。

实现通用逻辑(如序列化工具)。

模块化限制:Java 9+ 模块化系统需显式开放反射权限。


四、面试回答示例

问题:请解释 Java 反射的实现原理及用途。
回答

Java 反射的核心是通过 JVM 在运行时动态获取类的元数据(如方法、字段、构造器),并操作这些信息。
实现原理

类加载时,JVM 生成唯一的 Class 对象,存储类的结构信息。

反射通过 Class 对象访问 Field、Method、Constructor 等元数据。

调用 setAccessible(true) 可突破私有成员的访问限制。

主要用途

框架开发:如 Spring 的依赖注入、MyBatis 的 ORM 映射。

动态代理:JDK 动态代理生成代理类。

通用工具:JSON 序列化库(如 Jackson)通过反射解析字段。

测试工具:JUnit 通过反射调用测试方法。

注意事项:反射性能较低,且可能破坏封装性,需谨慎使用。


通过掌握反射的机制和应用场景,可以更好地理解 Java 高级特性及主流框架的设计思想

相关推荐

作为后端开发,你知道MyBatis有哪些隐藏的 “宝藏” 扩展点吗?

在互联网大厂后端开发领域,MyBatis作为一款主流的持久层框架,凭借其灵活的配置与强大的数据处理能力,广泛应用于各类项目之中。然而,随着业务场景日趋复杂、系统规模不断扩张,开发过程中常面临SQL...

基于Spring+SpringMVC+Mybatis分布式敏捷开发系统架构(附源码)

前言zheng项目不仅仅是一个开发架构,而是努力打造一套从前端模板-基础框架-分布式架构-开源项目-持续集成-自动化部署-系统监测-无缝升级的全方位J2EE企业级开发解...

基于Java实现,支持在线发布API接口读取数据库,有哪些工具?

基于java实现,不需要编辑就能发布api接口的,有哪些工具、平台?还能一键发布、快速授权和开放提供给第三方请求调用接口的解决方案。架构方案设计:以下是一些基于Java实现的无需编辑或只需少量编辑...

Mybatis Plus框架学习指南-第三节内容

自动填充字段基本概念MyBatis-Plus提供了一个便捷的自动填充功能,用于在插入或更新数据时自动填充某些字段,如创建时间、更新时间等。原理...

被你误删了的代码,在 IntelliJ IDEA中怎么被恢复

在IntelliJIDEA中一不小心将你本地代码给覆盖了,这个时候,你ctrl+z无效的时候,是不是有点小激动?我今天在用插件mybatisgenerator自动生成mapper的时候,...

修改 mybatis-generator 中数据库类型和 Java 类型的映射关系

使用mybatis-generator发现数据库类型是tinyint(4),生成model时字段类型是Byte,使用的时候有点不便数据库的类型和Model中Java类型的关系...

又被问到了, java 面试题:反射的实现原理及用途?

一、反射的实现原理反射(Reflection)是Java在运行时动态获取类的元数据(如方法、字段、构造器等)并操作类对象的能力。其核心依赖于...

Spring Boot 中JPA和MyBatis技术那个更好?

你在进行SpringBoot项目开发时,是不是也经常在选择JPA和MyBatis这两个持久化技术上犯难?面对众多前辈的经验之谈,却始终拿不准哪种技术才最适合自己的项目?别担心,今天咱们就...

Spring Boot (七)MyBatis代码自动生成和辅助插件

一、简介1.1MyBatisGenerator介绍MyBatisGenerator是MyBatis官方出品的一款,用来自动生成MyBatis的mapper、dao、entity的框架,让...

解决MyBatis Generator自动生成.java.1文件

MyBatis框架操作数据库,一张表对应着一个实体类、一个Mapper接口文件、一个Mapper映射文件。一个工程项目通常最少也要几十张表,那工作量可想而知非常巨大的,MyBatis框架替我们想好了解...

Linux yq 命令使用详解

简介yq是一个轻量级、可移植的命令行...

7 段不到 50 行的 Python 脚本,解决 7 个真实麻烦:代码、场景与可复制

“...

Python学不会来打我(62) json数据操作汇总

很多小伙伴学了很久的python一直还是没有把数据类型之间的转换搞明白,上一篇文章我们详细分享了python的列表、元组、字典、集合之间的相互转换,这一篇文章我们来分享json数据相关的操作,虽然严格...

之前3W买的Python全系列教程完整版(懂中文就能学会)

今天给大家带来了干货,Python入门教程完整版,完整版啊!完整版!言归正传,小编该给大家介绍一下这套教程了,希望每个小伙伴都沉迷学习,无法自拔...

x-cmd pkg | grex - 正则表达式生成利器,解决手动编写的烦恼

简介grex是一个旨在简化创作正则表达式的复杂且繁琐任务的库和命令行程序。这个项目最初是DevonGovett编写的JavaScript工具regexgen的Rust移植。但re...

取消回复欢迎 发表评论: