【反射】Java反射 全方位知识体系(附 应用场景 + 《八股文常考面试题》)

news2026/3/24 20:43:15
文章目录Java反射一、基础概念1. 定义2. 核心原理二、核心类库三、基本操作1. 获取 Class 对象的三种方式2. 实例化对象3. 访问字段4. 调用方法5. 操作构造器四、高级特性1. 反射与泛型2. 反射与注解3. 动态代理五、应用场景1. 框架开发2. 注解处理3. 动态扩展4. 调试与工具六、优缺点分析1. 优点2. 缺点七、注意事项与最佳实践1. 性能优化2. 安全问题3. 代码规范4. 版本兼容性Java反射核心应用场景一、框架开发最核心场景1. Spring IoC控制反转容器2. Spring AOP面向切面编程3. MyBatis ORM映射二、注解处理1. 单元测试框架JUnit2. 自定义注解实现业务逻辑三、动态扩展与插件化1. Java SPIService Provider Interface机制2. 插件化开发四、动态代理五、调试与工具类1. IDE代码补全与类结构查看2. 反射工具库六、实际业务场景1. 动态加载配置类2. 对象拷贝BeanUtils3. JSON序列化/反序列化总结反射的核心价值Java反射-八股文常考面试题一、基础概念篇1. 什么是Java反射2. 反射的核心原理是什么3. 获取Class对象的三种方式高频二、核心操作篇1. 如何通过反射实例化对象2. 如何访问/修改字段Field3. 如何调用方法Method4. setAccessible(true)的作用与风险三、应用场景篇1. 反射在框架中的应用高频2. 动态代理与反射的关系3. 注解处理如JUnit Test四、优缺点与性能篇1. 反射的优缺点2. 反射为什么慢如何优化五、进阶原理篇1. 泛型擦除后如何通过反射获取泛型信息2. JDK动态代理 vs CGLIB动态代理高频3. Java 9模块系统对反射的影响Java反射一、基础概念1. 定义Java反射是指在运行时动态获取类的元信息如类的结构、方法、字段、构造器等并能动态操作类或对象的能力如实例化对象、调用方法、修改字段值。它是Java动态性的核心体现。2. 核心原理Class对象反射的入口。每个类被加载后JVM会自动生成一个java.lang.Class对象该对象包含了类的完整元数据。类加载机制反射依赖于JVM的类加载过程加载→链接→初始化通过Class对象可逆向访问类的结构信息。二、核心类库反射主要依赖java.lang和java.lang.reflect包下的类核心类如下类名作用说明java.lang.Class反射的入口类代表类的元数据可获取类的构造器、方法、字段等信息。Constructor代表类的构造方法可用于实例化对象。Method代表类的方法可用于动态调用方法。Field代表类的字段成员变量可用于动态获取或修改字段值。Modifier工具类用于解析类、方法、字段的修饰符如public、static、final。Array工具类用于动态创建和访问数组。ParameterizedType代表参数化类型如ListString可获取泛型的实际类型参数。Annotation代表注解可通过反射获取类、方法、字段上的注解信息。三、基本操作1. 获取 Class 对象的三种方式类名.class编译时确定最安全如String.class。对象.getClass()通过实例获取如hello.getClass()。Class.forName(“全限定类名”)动态加载需处理ClassNotFoundException如Class.forName(java.util.ArrayList)。2. 实例化对象通过Class.newInstance()调用无参构造器Java 9后过时推荐用Constructor。通过Constructor.newInstance(Object... initargs)可调用有参构造器需先获取Constructor对象。3. 访问字段获取字段getField(String name)获取public字段包括父类。getDeclaredField(String name)获取所有声明的字段包括私有不包括父类。操作字段值get(Object obj)获取字段值。set(Object obj, Object value)设置字段值。私有字段需调用setAccessible(true)打破封装。4. 调用方法获取方法getMethod(String name, Class?... parameterTypes)获取public方法包括父类。getDeclaredMethod(String name, Class?... parameterTypes)获取所有声明的方法包括私有不包括父类。调用方法invoke(Object obj, Object... args)执行方法静态方法obj传null。私有方法需调用setAccessible(true)。5. 操作构造器getConstructor(Class?... parameterTypes)获取public构造器。getDeclaredConstructor(Class?... parameterTypes)获取所有构造器包括私有。四、高级特性1. 反射与泛型由于Java泛型在编译时会类型擦除运行时需通过反射获取泛型信息Field.getGenericType()返回字段的泛型类型如ParameterizedType。ParameterizedType.getActualTypeArguments()获取泛型的实际类型参数如ListString中的String。2. 反射与注解可通过反射获取类、方法、字段上的注解getAnnotation(ClassT annotationClass)获取指定类型的注解。getAnnotations()获取所有注解包括继承的。getDeclaredAnnotations()获取直接声明的注解不包括继承的。3. 动态代理反射是动态代理的基础核心类Proxy用于创建代理对象。InvocationHandler处理代理方法的调用逻辑。示例Proxy.newProxyInstance(ClassLoader loader, Class?[] interfaces, InvocationHandler h)。五、应用场景1. 框架开发Spring IoC通过反射实例化Bean读取配置文件中的类名并动态加载。Spring AOP基于动态代理反射实现实现方法拦截。MyBatis通过反射映射SQL结果到Java对象调用Mapper接口方法。2. 注解处理JUnit通过反射识别Test注解并执行测试方法。自定义注解结合反射实现权限校验、日志记录等功能。3. 动态扩展SPI机制ServiceLoader通过反射加载配置文件中定义的实现类。插件化开发动态加载外部Jar包中的类并调用其方法。4. 调试与工具IDE通过反射提供代码补全、类结构查看等功能。反射工具类如Apache Commons Lang的FieldUtils、MethodUtils。六、优缺点分析1. 优点动态性运行时才确定类和方法提高代码灵活性。通用性可编写通用代码处理不同类如框架的通用工具。解耦减少硬编码便于扩展和维护。2. 缺点性能开销比直接调用慢涉及动态类型解析、安全检查频繁调用需缓存反射对象。安全风险可访问私有成员破坏封装性需合理控制权限。可读性差反射代码晦涩难懂调试和维护成本高。七、注意事项与最佳实践1. 性能优化缓存Class、Constructor、Method、Field对象避免重复获取。尽量减少setAccessible(true)的使用或仅在初始化时调用一次。2. 安全问题Java 9模块系统中若模块未opens给其他模块setAccessible会抛出InaccessibleObjectException需在module-info.java中声明opens。合理使用SecurityManagerJava 17后默认禁用限制反射权限。3. 代码规范避免过度使用反射能用直接调用则不用反射。处理反射异常如IllegalAccessException、InvocationTargetException避免吞异常。4. 版本兼容性关注Java版本对反射的调整如Java 9模块系统、Java 16对非法反射访问的警告升级为错误。Java反射核心应用场景反射的核心价值在于运行时动态性与解耦能力以下是其最经典、最常用的落地场景一、框架开发最核心场景1. Spring IoC控制反转容器作用通过反射动态实例化Bean并管理依赖注入避免硬编码。原理读取XML配置/注解如Component、Bean中的类全限定名。调用Class.forName()加载类通过Constructor.newInstance()实例化对象。通过反射调用setter方法或直接注入字段Field.set()完成依赖装配。示例!-- Spring XML配置 --beaniduserServiceclasscom.example.UserServicepropertynameuserDaorefuserDao//beanSpring内部通过反射解析上述配置动态创建UserService并注入UserDao。2. Spring AOP面向切面编程作用基于动态代理反射实现实现方法拦截用于日志、事务、权限控制等横切关注点。原理JDK动态代理通过Proxy.newProxyInstance()创建代理对象InvocationHandler.invoke()内部用反射调用目标方法。CGLIB动态代理通过字节码生成子类重写方法时用反射调用父类原方法。3. MyBatis ORM映射作用将SQL查询结果自动映射到Java对象无需手动set字段。原理通过反射获取实体类的所有字段Class.getDeclaredFields()。根据字段名匹配SQL结果集的列名。调用Field.set()将列值注入到对象字段私有字段需setAccessible(true)。示例// MyBatis Mapper接口Select(SELECT id, name FROM user WHERE id #{id})UserselectUserById(intid);MyBatis内部通过反射调用该接口方法并将结果映射为User对象。二、注解处理1. 单元测试框架JUnit作用自动识别并执行带Test注解的方法。原理扫描测试类通过反射获取所有方法Class.getDeclaredMethods()。检查方法是否标注TestMethod.isAnnotationPresent(Test.class)。对标注方法通过Method.invoke()执行测试。2. 自定义注解实现业务逻辑场景权限校验、日志记录、参数校验等。示例自定义RequirePermission注解结合反射实现接口权限控制// 自定义注解Target(ElementType.METHOD)Retention(RetentionPolicy.RUNTIME)publicinterfaceRequirePermission{Stringvalue();// 所需权限}// 切面/拦截器中通过反射校验publicvoidcheckPermission(Methodmethod){if(method.isAnnotationPresent(RequirePermission.class)){StringrequiredPermmethod.getAnnotation(RequirePermission.class).value();// 校验当前用户是否拥有requiredPerm权限}}三、动态扩展与插件化1. Java SPIService Provider Interface机制作用动态加载外部实现类实现框架的可扩展性。原理在META-INF/services目录下定义接口文件内容为实现类全限定名。ServiceLoader通过反射读取文件调用Class.forName()加载实现类并实例化。示例JDBC驱动加载、Dubbo扩展点加载均基于SPI。2. 插件化开发场景IDE插件、应用市场插件、模块化系统。原理动态加载外部Jar包URLClassLoader。通过反射获取插件类调用约定的接口方法如Plugin.execute()。四、动态代理作用在不修改原代码的情况下对方法进行增强如日志、监控、事务。分类JDK动态代理基于接口通过Proxy和InvocationHandler实现核心是反射。CGLIB动态代理基于继承通过字节码生成子类内部也依赖反射调用父类方法。JDK动态代理示例// 目标接口publicinterfaceUserService{voidaddUser();}// 目标实现类publicclassUserServiceImplimplementsUserService{publicvoidaddUser(){System.out.println(添加用户);}}// 调用处理器publicclassLogHandlerimplementsInvocationHandler{privateObjecttarget;publicLogHandler(Objecttarget){this.targettarget;}publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println(前置日志);Objectresultmethod.invoke(target,args);// 反射调用目标方法System.out.println(后置日志);returnresult;}}// 创建代理对象UserServiceproxy(UserService)Proxy.newProxyInstance(UserServiceImpl.class.getClassLoader(),UserServiceImpl.class.getInterfaces(),newLogHandler(newUserServiceImpl()));proxy.addUser();// 调用代理方法五、调试与工具类1. IDE代码补全与类结构查看原理IDE通过反射加载项目类获取类的方法、字段、构造器等信息实时展示给开发者。2. 反射工具库场景简化反射操作避免重复代码。示例Apache Commons Lang的FieldUtils、MethodUtils封装了字段/方法的获取、设置、调用等操作。Spring的ReflectionUtils提供findField()、invokeMethod()等便捷方法。六、实际业务场景1. 动态加载配置类场景根据配置文件动态切换数据源、策略类等。示例StringstrategyClassconfig.getProperty(payment.strategy);// 从配置读取类名PaymentStrategystrategy(PaymentStrategy)Class.forName(strategyClass).newInstance();strategy.pay();// 动态调用策略方法2. 对象拷贝BeanUtils原理通过反射获取源对象的所有字段将值复制到目标对象的对应字段。示例Spring的BeanUtils.copyProperties(source, target)、Apache Commons BeanUtils的BeanUtils.copyProperties()。3. JSON序列化/反序列化原理序列化通过反射获取对象的所有字段将字段名和值转换为JSON。反序列化通过反射实例化对象根据JSON键名匹配字段并注入值。示例Jackson、Gson等JSON库的核心实现均依赖反射。总结反射的核心价值价值点说明动态性运行时才确定类、方法、字段无需编译期硬编码。解耦减少类之间的直接依赖提高代码扩展性如框架可插拔、策略动态切换。通用性编写通用代码处理不同类如ORM映射、对象拷贝、JSON序列化。Java反射-八股文常考面试题一、基础概念篇1. 什么是Java反射Java反射是指在运行时动态获取类的元信息如构造器、方法、字段、注解等并能动态操作类或对象的能力实例化对象、调用方法、修改字段值。它是Java动态性的核心体现。2. 反射的核心原理是什么每个类被JVM加载后会自动生成一个java.lang.Class对象该对象包含类的完整元数据结构、方法、字段等。反射通过Class对象逆向访问类的信息无需在编译期确定具体类。3. 获取Class对象的三种方式高频方式示例特点类名.classString.class编译期确定最安全对象.getClass()hello.getClass()通过实例获取Class.forName(“全限定名”)Class.forName(java.util.ArrayList)动态加载需处理异常二、核心操作篇1. 如何通过反射实例化对象方式1Class.newInstance()Java 9过时调用无参构造器。方式2Constructor.newInstance(Object... args)可调用有参构造器推荐。ConstructorUserconstructorUser.class.getDeclaredConstructor(String.class,int.class);constructor.setAccessible(true);// 若构造器私有需打破封装Useruserconstructor.newInstance(张三,25);2. 如何访问/修改字段Field获取字段getField(String name)获取public字段含父类。getDeclaredField(String name)获取所有声明字段含私有不含父类。操作字段get(Object obj)获取字段值。set(Object obj, Object value)设置字段值。私有字段需调用setAccessible(true)。3. 如何调用方法Method获取方法getMethod(String name, Class?... paramTypes)获取public方法含父类。getDeclaredMethod(String name, Class?... paramTypes)获取所有声明方法含私有不含父类。调用方法invoke(Object obj, Object... args)执行方法静态方法obj传null。私有方法需调用setAccessible(true)。4.setAccessible(true)的作用与风险作用打破Java的访问修饰符限制可访问私有成员构造器、方法、字段。风险破坏封装性可能导致对象状态不一致。Java 9模块系统中若模块未opens给其他模块会抛出InaccessibleObjectException。三、应用场景篇1. 反射在框架中的应用高频Spring IoC读取配置文件/注解中的类名通过反射实例化Bean并管理依赖。Spring AOP基于动态代理反射实现实现方法拦截如日志、事务。MyBatis通过反射将SQL结果映射到Java对象调用Mapper接口方法。2. 动态代理与反射的关系动态代理的核心是反射JDK动态代理通过Proxy.newProxyInstance()创建代理对象内部依赖InvocationHandler的invoke()方法通过反射调用目标方法。3. 注解处理如JUnitTestJUnit通过反射扫描测试类识别Test注解的方法然后通过反射调用这些方法执行测试。四、优缺点与性能篇1. 反射的优缺点优点缺点动态性运行时确定类和方法灵活性高性能开销比直接调用慢通用性可编写通用代码处理不同类安全风险可访问私有成员破坏封装解耦减少硬编码便于扩展可读性差代码晦涩维护成本高2. 反射为什么慢如何优化慢的原因运行时动态类型解析、安全检查如访问修饰符校验。每次调用反射方法都需重新查找元数据。优化方式缓存Class、Constructor、Method、Field对象避免重复获取。尽量减少setAccessible(true)的使用或仅在初始化时调用一次。五、进阶原理篇1. 泛型擦除后如何通过反射获取泛型信息Java泛型在编译期会类型擦除但可通过以下方式获取Field.getGenericType()返回字段的泛型类型如ParameterizedType。ParameterizedType.getActualTypeArguments()获取泛型的实际类型参数如ListString中的String。2. JDK动态代理 vs CGLIB动态代理高频维度JDK动态代理CGLIB动态代理实现方式基于反射要求目标类实现接口基于继承通过字节码生成子类限制只能代理实现接口的类可代理普通类不能是final类性能略低反射调用略高字节码生成Spring默认选择目标类实现接口时使用目标类未实现接口时使用3. Java 9模块系统对反射的影响模块系统Project Jigsaw引入module-info.java若模块未通过opens关键字将包开放给其他模块反射调用setAccessible(true)会抛出InaccessibleObjectException。解决方式在module-info.java中声明opens 包名 to 目标模块;。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2445096.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…