Java 反射机制详解
在 Java 编程世界中,反射机制犹如一把神奇的钥匙,它能够打开许多隐藏在代码深处的 “大门”,让开发者突破常规的限制,实现一些极具灵活性的功能。今天,就跟随我一同深入探究 Java 反射机制的奥秘。
一、什么是反射
反射是 Java 语言提供的一种强大机制,它允许程序在运行时动态地获取类的各种信息,比如类的成员变量、方法、构造函数等,并且能够实例化对象、调用方法以及访问和修改成员变量的值,而这些操作在编译期并不需要明确知道类的具体细节。
简单来说,正常情况下,我们编写代码时都是明确地引用类,例如创建一个类的对象:Person person = new Person(); 这里我们清楚知道 Person 类的结构。但反射却可以让我们在运行时才决定要操作哪个类,比如根据用户输入的类名去实例化相应的对象,就像拥有了动态操控代码的超能力。
二、反射的核心类
Java 反射机制主要依托于 java.lang.reflect 包下的几个核心类:
- Class 类:这是反射的入口,它代表一个类的运行时表示。每一个加载到 Java 虚拟机(JVM)中的类都有一个与之对应的 Class 对象,可以通过多种方式获取,例如 Class.forName("全限定类名")、类名.class 以及对象的 getClass() 方法。获取到 Class 对象后,就能以此为起点探索类的各种信息。
- Constructor 类:用于表示类的构造函数,可以通过 Class 对象获取类的所有构造函数,然后利用构造函数来创建类的实例,即使是私有的构造函数,反射也能访问并调用(当然,私有的构造函数通常有其特定的访问限制原因,滥用反射去调用可能破坏类的封装性)。
- Method 类:对应类的方法,能获取方法的签名、参数类型、返回值类型等信息,并且使用反射可以在对象上动态调用这些方法,就如同在运行时临时拼凑出方法调用的指令一样。
- Field 类:用来表示类的成员变量,通过它可以获取成员变量的类型、访问修饰符,以及读写成员变量的值,这意味着可以突破常规的访问权限控制,直接修改那些本应是私有的变量(不过同样要谨慎使用,以免造成难以排查的错误)。
三、反射的基本使用示例
(一)获取 Class 对象
以下是几种常见获取 Class 对象的方式:
// 方式一:使用 Class.forName(),常用于根据类名动态加载类
Class<?> clazz1 = Class.forName("com.example.demo.Person");
// 方式二:类名.class,常用于在已知类的情况下获取其 Class 对象,常用于参数传递等场景
Class<Person> clazz2 = Person.class;
// 方式三:通过对象的 getClass() 方法,获取该对象所属类的 Class 对象
Person person = new Person();
Class<? extends Person> clazz3 = person.getClass();
(二)创建实例
假设我们有一个简单的 Person 类:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 省略 getters 和 setters
}
使用反射创建 Person 类实例:
try {
Class<?> personClass = Class.forName("com.example.demo.Person");
Constructor<?> constructor = personClass.getConstructor(String.class, int.class);
Person person = (Person) constructor.newInstance("张三", 20);
System.out.println(person.getName() + " : " + person.getAge());
} catch (Exception e) {
e.printStackTrace();
}
这里先获取到 Person 类的 Class 对象,接着拿到对应的构造函数,最后通过构造函数创建出实例。
(三)调用方法
继续以上述 Person 类为例,假设 Person 类有一个 sayHello 方法:
public void sayHello() {
System.out.println("Hello, I'm " + name);
}
使用反射调用该方法:
try {
Class<?> personClass = Class.forName("com.example.demo.Person");
Constructor<?> constructor = personClass.getConstructor(String.class, int.class);
Person person = (Person) constructor.newInstance("张三", 20);
Method method = personClass.getMethod("sayHello");
method.invoke(person);
} catch (Exception e) {
e.printStackTrace();
}
先创建实例,再获取 sayHello 方法对应的 Method 对象,最后通过 invoke 方法在实例上调用该方法。
(四)访问成员变量
还是针对 Person 类,访问其私有成员变量 name:
try {
Class<?> personClass = Class.forName("com.example.demo.Person");
Constructor<?> constructor = personClass.getConstructor(String.class, int.class);
Person person = (Person) constructor.newInstance("张三", 20);
Field field = personClass.getDeclaredField("name");
field.setAccessible(true); // 取消私有访问限制,这一步很关键,否则无法访问私有变量
String name = (String) field.get(person);
System.out.println("The name is: " + name);
} catch (Exception e) {
e.printStackTrace();
}
通过 getDeclaredField 获取成员变量,设置可访问后就能获取到变量的值。
四、反射的应用场景
(一)框架开发
像 Spring 这样的大型框架广泛使用反射机制。在依赖注入环节,框架需要根据配置文件或注解信息动态地创建类的实例、调用初始化方法等,将各个组件组装起来,而不用在编译时就硬编码所有的依赖关系,使得代码的扩展性和维护性大大增强。
(二)动态代理
实现 Java 的动态代理模式离不开反射。通过创建代理类,在运行时动态生成代理对象,代理对象能够拦截对目标对象方法的调用,添加额外的逻辑,如日志记录、权限验证等,然后再将方法调用转发给目标对象,这种动态生成代码逻辑的能力让程序更加灵活。
(三)插件化开发
一些支持插件扩展的应用,利用反射来加载外部的插件类。应用程序在运行时扫描指定目录下的插件 JAR 文件,通过反射将插件中的类加载进来,集成到主程序流程中,从而实现功能的动态扩展,用户无需重新编译整个应用就能添加新功能。
五、反射的优缺点
(一)优点
- 极大的灵活性:能够突破静态语言在编译期类型绑定的限制,根据运行时情况动态操作类,适应多变的业务需求。
- 利于框架构建:使得框架开发者可以编写通用的、高度抽象的代码,框架使用者只需按照约定配置,框架就能自动适配处理,提升开发效率。
(二)缺点
- 性能开销:相较于直接的静态代码调用,反射涉及动态解析类信息、查找方法等操作,会消耗更多的系统资源,导致程序运行效率降低,所以在对性能敏感的核心代码部分,要谨慎使用反射。
- 破坏封装性:反射可以访问类的私有成员,这虽然在某些场景下提供了便利,但也容易让代码的封装边界变得模糊,使得类的内部实现细节暴露在外,增加代码维护的难度和出错的风险。
相关文章:
Java 反射机制详解
在 Java 编程世界中,反射机制犹如一把神奇的钥匙,它能够打开许多隐藏在代码深处的 “大门”,让开发者突破常规的限制,实现一些极具灵活性的功能。今天,就跟随我一同深入探究 Java 反射机制的奥秘。 一、什么是反射 反…...

【k8s】scc权限 restricted、anyuid、privileged
文章目录 概述1. 内置的scc2. OpenShift如何确定pod的scc2.1 Pod未带SCC标签的情况2.2. Pod带有SCC标签的情况 参考 概述 在OpenShift(后文简称OCP)中,很早就一个概念:Security Context Constraints ,简称SCC…...

2025华数杯国际赛A题完整论文讲解(含每一问python代码+数据+可视化图)
大家好呀,从发布赛题一直到现在,总算完成了2025“华数杯”国际大学生数学建模竞赛A题Can He Swim Faster的完整的成品论文。 本论文可以保证原创,保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文…...
ThreadLocal 的使用场景
在现代电商平台中,ThreadLocal 常用于以下场景,特别是与线程隔离相关的业务中,以提高性能和简化上下文传递。 1. 用户上下文信息管理 场景:在用户发起的每次请求中,需要携带用户 ID、角色、权限等信息,而这…...
后端开发 Springboot整合Redis Spring Data Redis 模板
目录 redis 配置 RedisConfig 类 完整代码 代码讲解 1. 类定义和注解 2. 定义 RedisTemplate Bean 3. 配置 JSON 序列化 4. 配置 Redis 的 key 和 value 序列化方式 5. 完成配置并返回 RedisTemplate 总结 redis 服务接口实现类 类级别 注入 RedisTemplate 常用 Re…...

代码随想录算法训练营第 4 天(链表 2)| 24. 两两交换链表中的节点19.删除链表的倒数第N个节点 -
一、24. 两两交换链表中的节点 题目:24. 两两交换链表中的节点 - 力扣(LeetCode) 视频:帮你把链表细节学清楚! | LeetCode:24. 两两交换链表中的节点_哔哩哔哩_bilibili 讲解:代码随想录 dummy-…...

【RDMA学习笔记】1:RDMA(Remote Direct Memory Access)介绍
从帝国理工的PPT学习。 什么是RDMA Remote Direct Memory Access,也就是Remote的DMA,是一种硬件机制,能直接访问远端结点的内存,而不需要处理器介入。 其中: Remote:跨node进行数据传输Directÿ…...
网络安全常见的35个安全框架及模型
大家读完觉得有帮助记得关注和点赞!!! 01、概述 网络安全专业机构制定的一套标准、准则和程序,旨在帮助组织了解和管理面临的网络安全风险。优秀的安全框架及模型应该为用户提供一种可靠方法,帮助其实现网络安全建设…...

Elasticsearch介绍及使用
Elasticsearch 是一款基于 Lucene 库构建的开源、分布式、RESTful 风格的搜索引擎和分析引擎,具有强大的全文搜索、数据分析、机器学习等功能,广泛应用于日志分析、实时数据分析、全文检索等场景。 核心概念 索引(Index)…...

Leetocde516. 最长回文子序列 动态规划
原题链接:Leetocde516. 最长回文子序列 class Solution { public:int longestPalindromeSubseq(string s) {int n s.size();vector<vector<int>> dp(n, vector<int>(n, 1));for (int i 0; i < n; i) {dp[i][i] 1;if (i 1 < n &&…...

iOS 逆向学习 - Inter-Process Communication:进程间通信
iOS 逆向学习 - Inter-Process Communication:进程间通信 一、进程间通信概要二、iOS 进程间通信机制详解1. URL Schemes2. Pasteboard3. App Groups 和 Shared Containers4. XPC Services 三、不同进程间通信机制的差异四、总结 一、进程间通信概要 进程间通信&am…...

高级生化大纲
一,蛋白质化学: 蛋白质分离是生物化学和分子生物学研究中的一项基本技术,用于根据蛋白质的物理和化学特性将其从混合物中分离出来。 1. 离心分离法 离心分离法利用离心力来分离不同质量或密度的颗粒和分子。 差速离心:通过逐…...

YARN WebUI 服务
一、WebUI 使用 与HDFS一样,YARN也提供了一个WebUI服务,可以使用YARN Web用户界面监视群集、队列、应用程序、服务、流活动和节点信息。还可以查看集群详细配置的信息,检查各种应用程序和服务的日志。 1.1 首页 浏览器输入http://node2.itc…...

【Unity3D】利用IJob、Burst优化处理切割物体
参考文章: 【Unity】切割网格 【Unity3D】ECS入门学习(一)导入及基础学习_unity ecs教程-CSDN博客 【Unity3D】ECS入门学习(十二)IJob、IJobFor、IJobParallelFor_unity ijobparallelfor-CSDN博客 工程资源地址&…...

【大前端】Vue3 工程化项目使用详解
目录 一、前言 二、前置准备 2.1 环境准备 2.1.1 create-vue功能 2.1.2 nodejs环境 2.1.3 配置nodejs的环境变量 2.1.4 更换安装包的源 三、工程化项目创建与启动过程 3.1 创建工程化项目 3.2 项目初始化 3.3 项目启动 3.4 核心文件说明 四、VUE两种不同的API风格 …...
基于文件系统分布式锁原理
分布式锁:在一个公共的存储服务上打上一个标记,如Redis的setnx命令,是先到先得方式获得锁,ZooKeeper有点像下面的demo,比较大小的方式判决谁获得锁。 package com.ldj.mybatisflex.demo;import java.util.*; import java.util.co…...
简历整理YH
一,订单中心 1,调拨单 融通(Rocketmq)-订单中心:ECC_BMS123(已出单),125(分配),127(发货),129(收货) 通过RocketMq接入多场景订单数据 2,销售单 sap(FTP)-订单中心,下发1002,1003,…...
Kotlin 协程基础三 —— 结构化并发(二)
Kotlin 协程基础系列: Kotlin 协程基础一 —— 总体知识概述 Kotlin 协程基础二 —— 结构化并发(一) Kotlin 协程基础三 —— 结构化并发(二) Kotlin 协程基础四 —— CoroutineScope 与 CoroutineContext Kotlin 协程…...
微信小程序实现长按录音,点击播放等功能,CSS实现语音录制动画效果
有一个需求需要在微信小程序上实现一个长按时进行语音录制,录制时间最大为60秒,录制完成后,可点击播放,播放时再次点击停止播放,可以反复录制,新录制的语音把之前的语音覆盖掉,也可以主动长按删…...

校园跑腿小程序---轮播图,导航栏开发
hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 🦁作者简介:一名喜欢分享和记录学习的在校大学生…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...