一、类

1.类的生命周期

1. 类的编译:通过 javac 命令将 .java 源文件编译成 .class 字节码文件。
2. 类的加载:类加载器(ClassLoader)将 .class 文件从硬盘加载到内存,形成“类对象”,包括加载、链接、初始化三个阶段。
3. 类的初始化和实例化:通过 new 关键字实例化类,创建具体对象。
4. 对象的生命周期:对象从创建到被垃圾回收器(GC)回收的整个过程。
5. 反射机制:允许在运行时动态加载类,扩展了类加载的灵活性。

二、 反射机制

Java 反射是指在运行时动态获取类的信息(如类名、方法、字段等)并操作类的能力。

三、反射的前提:获取 “类对象”

反射的所有操作,都必须基于一个核心载体 ——Class 类的对象(简称 “类对象”)。每个类在 JVM 中只会被加载一次,因此同一个类的类对象全局唯一。

1. 获取 Class 对象的三种方式

三种获取  Person  类的  Class  对象的方法

public class Test {public static void main(String[] args) throws ClassNotFoundException {// 1、硬盘阶段获取类对象Class class1 = Class.forName("com.qcby.reflect.Person");// 2、类阶段Class class2 = Person.class;// 3、对象阶段Person person = new Person();Class class3 = person.getClass();System.out.println(class1 == class2);System.out.println(class2 == class3);}
}

2.获取成员变量


2.1.读写变量值:set () 与 get ()

语法:
写值:field.set(对象实例, 变量值)(为指定对象的该变量赋值)
读值:field.get(对象实例)(获取指定对象的该变量值)
关键注意:若变量是 private 私有权限,直接读写会抛出 IllegalAccessException,需先调用 field.setAccessible(true) 开启 “暴力反射”,强制跳过权限检查。

2.2.应用

Person person = new Person();
// 获取类对象
Class pclass = Class.forName("com.qcby.reflect.Person");// 通过类对象获取成员变量们
Field[] fields = pclass.getDeclaredFields();
for (Field item : fields) {System.out.println(item);
}Field field_age = pclass.getDeclaredField("age");
System.out.println(field_age);Field[] public_fields = pclass.getFields();
for (Field item : public_fields) {System.out.println(item);
}Field field_from = pclass.getField("from");
System.out.println(field_from);// 获取和设置
field_from.set(person, "中国");
field_age.setAccessible(true);
field_age.set(person, 20);System.out.println(field_age.get(person));
System.out.println(field_from.get(person));
System.out.println(person);
// 1. 创建 Person 对象实例
Person person = new Person();
// 2. 获取类对象
Class pClass = Class.forName("reflect.Person");// 3. 获取所有成员变量(含 private)
Field[] allFields = pClass.getDeclaredFields();
for (Field field : allFields) {System.out.println(field); // 输出:private java.lang.String reflect.Person.name、private int reflect.Person.age、public java.lang.String reflect.Person.from
}// 4. 获取指定私有变量 name(需暴力反射)
Field nameField = pClass.getDeclaredField("name");
nameField.setAccessible(true); // 开启暴力反射,突破 private 限制
nameField.set(person, "赵嘉成"); // 赋值
System.out.println(nameField.get(person)); // 取值,输出:赵嘉成// 5. 获取指定公共变量 from(无需暴力反射)
Field fromField = pClass.getDeclaredField("from");
fromField.set(person, "中国"); // 直接赋值
System.out.println(person); // 输出:Person [name=赵嘉成, age=0, from=中国]

3.获取成员方法

3.1.执行方法:invoke ()

语法:method.invoke(对象实例, 方法参数值...)

若方法是静态方法(static),对象实例可传 null;
若方法无参数,参数值部分可省略或传空数组;
若方法有返回值,invoke() 会返回该值(需强转)。

权限注意:私有方法需先调用 method.setAccessible(true) 开启暴力反射。

3.2.执行代码

// 获取所有方法(包括私有)
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {System.out.println(method);
}// 调用私有方法
Method runMethod = clazz.getDeclaredMethod("run");
runMethod.setAccessible(true);
runMethod.invoke(person); // 执行方法

4.获取构造方法

构造方法的反射操作,核心是 “获取构造器” 和 “创建对象”(替代 new 关键字),支持通过无参 / 有参构造器创建实例。

返回类型方法签名(含形参)获取范围典型用途
Constructor<?>[]getDeclaredConstructors()所有构造器(包括 private)暴力反射,想拿到任意访问修饰符的构造器
Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes)指定一个构造器(包括 private)暴力反射,精确匹配形参列表
Constructor<?>[]getConstructors()仅 public 构造器正常反射,只关心公开构造器
Constructor<T>getConstructor(Class<?>... parameterTypes)指定一个 public 构造器正常反射,精确匹配形参列表且为 public

4.1 创建对象newInstance ()

语法:constructor.newInstance(构造参数值...)
无参构造器:参数值部分可省略,直接 constructor.newInstance();
有参构造器:需传入与参数列表匹配的参数值;
私有构造器:需先调用 constructor.setAccessible(true) 开启暴力反射。

// 1. 拿所有构造器(含 private)
Constructor<?>[] all = clazz.getDeclaredConstructors();// 2. 拿指定 private 构造器(如 Person(String, int))
Constructor<Person> c1 = clazz.getDeclaredConstructor(String.class, int.class);
c1.setAccessible(true);          // 暴力反射
Person p1 = c1.newInstance("Tom", 20);// 3. 拿所有 public 构造器
Constructor<?>[] pub = clazz.getConstructors();// 4. 拿指定 public 无参构造器
Constructor<Person> c2 = clazz.getConstructor();
Person p2 = c2.newInstance();

四、其他配置

1.步骤拆解与代码

创建配置文件(refconfig.properties):

# 配置要加载的类(全类名)
reflect.className=reflect.Person
# 配置要调用的方法名
reflect.methodName=getAge

2.获取类的基本信息

需求API示例结果
全限定名(包 + 类)clazz.getName()com.qcby.reflect.Person
简单类名clazz.getSimpleName()Person
包名clazz.getPackage().getName()com.qcby.reflect
父类clazz.getSuperclass()class java.lang.Object
实现的接口数组clazz.getInterfaces()[interface java.io.Serializable]
修饰符(public/private/…)Modifier.toString(clazz.getModifiers())public
是否为接口clazz.isInterface()FALSE
是否为数组clazz.isArray()FALSE
是否为枚举clazz.isEnum()FALSE
是否为注解clazz.isAnnotation()FALSE
是否为基本类型clazz.isPrimitive()FALSE

3.常见问题

​​1.反射能修改final字段吗?​​

可以,但需要先调用setAccessible(true)。

​​2.反射如何获取父类的方法?

​​使用getSuperclass()和getDeclaredMethods()。

3.​​反射为什么慢?​​

反射调用需要检查访问权限、动态解析方法名,无法被JIT优化。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【论文笔记】VGGT-从2D感知3D:pose估计+稠密重建+点跟踪

VGG组联合Meta改进了dust3r&#xff0c;输入图片&#xff0c;输出对应的一系列3D属性&#xff0c;被CVPR2025收录&#xff01;1.abstract我们提出了VGGT&#xff0c;一种前馈神经网络&#xff0c;能够直接从场景的一个、几个或数百个视角推断出所有关键的3D属性&#xff0c;包括…

idea2025.2中maven编译中文乱码

问题描述&#xff1a;使用idea2025.2编译器中maven编译java文件后中文出现乱码情况解决方案&#xff1a;添加指令&#xff1a; JAVA_TOOL_OPTIONS-Dfile.encodingUTF-8 在下图位置注意&#xff1a;再次编译时&#xff0c;可以在原本文件中小范围修改一点内容&#xff08;打个…

【适度精简】Windows 7 旗舰版-emmy精简系统

Windows 7旗舰版曾是非常受欢迎的操作系统&#xff0c;但随着时间推移和技术发展&#xff0c;其在一些场景下暴露出了诸多问题&#xff0c;适度精简的Windows 7旗舰版正是为解决这些问题而出现&#xff0c;以下是从用户软件痛点角度对其背景和作用的分析。 添加图片注释&#x…

数据分析编程第七步:分析与预测

7.1 销售趋势分析利用历史销售数据统计月销售额&#xff0c;计算季节化因子&#xff0c;获取去季节化销售数据&#xff0c;然后进行线性拟合&#xff0c;最后预测接下来的某个月的销售额。第一步&#xff1a;读数&#xff0c;统计月销售额A1file(“sales.csv”).importtc(order…

【web3】十分钟了解web3是什么?

十分钟了解web3是什么?Web3的核心概念区块链与去中心化智能合约加密货币与代币去中心化应用&#xff08;DApps&#xff09;钱包与身份验证DAO&#xff08;去中心化自治组织&#xff09;Web3 国内产品Web3 国际产品Web3 基础设施Web3 应用场景技术实现特点挑战与未来Web3的核心…

联合体和枚举——嵌入式学习笔记

目录 前言 一、联合体&#xff08;共用体&#xff09; 1、基本概念 2、初始化和引用 &#xff08;1&#xff09;初始化 &#xff08;2&#xff09;引用 二、枚举 前言 在C语言的编程世界中&#xff0c;我们早已熟悉了结构体struct这种能将不同数据类型捆绑在一起的“打包…

SRE命令行兵器谱之思想篇:像SRE一样思考——命令行不只是工具,更是你的战友

SRE命令行兵器谱之思想篇:像SRE一样思考——命令行不只是工具,更是你的战友 欢迎来到《SRE命令行兵器谱》系列。在深入研究 grep, lsof, tcpdump 这些强大“兵器”的细节之前,我们必须先回答一个更重要的问题: 一个SRE(网站可靠性工程师)在黑色的终端窗口前,脑子里想的…

STL库——list(类模拟实现)

ʕ • ᴥ • ʔ づ♡ど &#x1f389; 欢迎点赞支持&#x1f389; 个人主页&#xff1a;励志不掉头发的内向程序员&#xff1b; 专栏主页&#xff1a;C语言&#xff1b; 文章目录 前言 一、基本框架 二、构造函数 三、析构函数 四、赋值重载 五、增删查改 5.1、push_front/pus…

在PowerPoint和WPS演示让蝴蝶一直跳8字舞

如何让PPT中插入的对象按指定的轨迹运动并且一直“停不下来”&#xff1f;简单三步&#xff1a;①插入对象、②设置路径动画、③设置动画重复。本文以蝴蝶图片一直跳8字舞为例进行实际操作讲解&#xff0c;PowerPoint和WPS演示都一样操作&#xff0c;本文以WPS演示进行讲解。第…

并发编程——06 JUC并发同步工具类的应用实战

0 常用并发同步工具类的真实应用场景JDK 提供了比synchronized更加高级的各种同步工具&#xff0c;包括ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier等&#xff0c;可以实现更加丰富的多线程操作&#xff1b;1 ReentrantLock&#xff08;可重入的占用锁&#xff0…

Apple登录接入记录

Apple文档——通过 Apple 登录 使用入门 - 通过 Apple 登录 - Apple Developer Apple文档——设计要求——登录通过 Apple 登录 | Apple Developer Documentation 插件github版——apple-signin-unity&#xff08;README 中为接入步骤&#xff09; GitHub - lupidan/apple-…

【小程序-慕尚花坊04】网络请求并发与loading

网络请求并发与loading一&#xff0c;网络请求并发与loading1&#xff0c;并发处理1.1&#xff0c;异步实现方式2.2&#xff0c;Promise.all异步方式封装2&#xff0c;loading加载2.1&#xff0c;loading的基本使用2.2&#xff0c;loading与并发结合案例2.3&#xff0c;loading…

CentOS 7 升级 OpenSSH 10.0p2 完整教程(含 Telnet 备份)

&#x1f539; CentOS 7 升级 OpenSSH 10.0p2 完整教程&#xff08;含 Telnet 备份&#xff09; 注意&#xff1a;为了避免升级 SSH 时无法远程登录&#xff0c;建议先启用 Telnet 服务 作为备用连接方式。 CentOS 7 默认 OpenSSH 版本是 7.x&#xff0c;升级到 10.0p2 需要 源…

aragfw9.dll aqnky-ef.dll aqua dock.dll apscon~1.dll apropdll.dll app_web_yqnqasrp.dll app_web_

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

rabbitMQ延时队列实现,怎么保证消息的幂等

一、RabbitMQ 延时队列实现方式 基于 TTL&#xff08;Time-To-Live&#xff09; 死信队列&#xff08;Dead Letter Queue&#xff09; 这是最常用的实现方式&#xff0c;核心思路是&#xff1a; (1)消息设置过期时间&#xff08;TTL&#xff09; (2)消息过期后进入绑定的死信队…

前沿技术观察:从AI 时代到量子计算的下一站

前沿技术观察&#xff1a;从AI 时代到量子计算的下一站&#x1f680; 技术的浪潮一波接一波&#xff0c;从 人工智能 到 区块链&#xff0c;再到 边缘计算、元宇宙、量子计算&#xff0c;这些前沿技术正在深刻影响我们的生活与产业格局。 对于开发者和技术爱好者来说&#xff0…

通过Kubernetes安装mysql5服务

以下是清晰、结构化的操作流程优化说明&#xff0c;按步骤梳理从部署到配置持久化、暴露服务的完整过程&#xff1a;一、基础部署&#xff1a;快速验证 MySQL 可用性创建有状态工作负载进入 KubeSphere 项目 → 工作负载 → 有状态副本集 → 创建&#xff0c;选择 通过镜像创建…

【mysql】SQL 中 IS 与 = 的区别:一个 NULL 值引发的思考

SQL 中 IS 与 的区别&#xff1a;一个 NULL 值引发的思考为什么查询结果总是少一条数据&#xff1f;可能是 NULL 在捣鬼在 SQL 查询中&#xff0c;很多开发者都曾遇到过这样的困惑&#xff1a;明明看起来正确的查询语句&#xff0c;返回的结果却总是与预期不符。这往往是因为没…

openGauss笔记

1、安装 直接用docker安装 2、国产化 符合国产化要求 3、客户端 3.1 dbeaver 社区版本&#xff08;25.1.4&#xff09;即可&#xff0c;驱动建议用离线版本&#xff0c;在官网下载最新的&#xff0c;然后在驱动管理里面进行添加本地的jar 3.1.1 驱动配置3.1.2 依赖 需要java版本…

SQL语言增删改查之C与R

本节通关要求1、掌握 SQL 语句对数据库进行的创建 Create 和读取 Retireve 操作的指令&#xff1b;2、多练习&#x1f3ae;说明&#xff1a;操作对象是数据表中的数据行&#xff0c;也就是表中的记录。请明确操作对象&#xff0c;不要误伤友军。背景&#xff1a;create table i…