当前位置: 首页 > news >正文

Java 反射(Reflection)

Java 反射(Reflection)

Java 反射(Reflection)是一个强大的特性,它允许程序在运行时查询、访问和修改类、接口、字段和方法的信息。反射提供了一种动态地操作类的能力,这在很多框架和库中被广泛使用,例如Spring框架的依赖注入。

反射 API

Java 的反射 API 提供了一系列的类和接口来操作 Class 对象。主要的类包括:

  • java.lang.Class:表示类的对象。提供了方法来获取类的字段、方法、构造函数等。
  • java.lang.reflect.Field:表示类的字段(属性)。提供了访问和修改字段的能力。
  • java.lang.reflect.Method:表示类的方法。提供了调用方法的能力。
  • java.lang.reflect.Constructor:表示类的构造函数。提供了创建对象的能力。

工作流程

  1. 获取 Class 对象:首先获取目标类的 Class 对象。
  2. 获取成员信息:通过 Class 对象,可以获取类的字段、方法、构造函数等信息。
  3. 操作成员:通过反射 API 可以读取和修改字段的值、调用方法以及创建对象。

以下是 Java 反射的基本使用方式及其常见应用。

1. 获取 Class 对象

每个类在 JVM 中都有一个与之相关的 Class 对象。可以通过以下方式获取 Class 对象:

通过类字面量

Class<?> clazz = String.class;

通过对象实例:

String str = "Hello";
Class<?> clazz = str.getClass();

通过 Class.forName() 方法:

Class<?> clazz = Class.forName("java.lang.String");

2. 创建对象

可以使用反射动态创建对象:

Class<?> clazz = Class.forName("java.lang.String");
Object obj = clazz.getDeclaredConstructor().newInstance();

3. 访问字段

可以通过反射访问和修改类的字段:

Class<?> clazz = Person.class;
Field field = clazz.getDeclaredField("name");
field.setAccessible(true); // 如果字段是私有的,需要设置为可访问
Object value = field.get(personInstance); // 获取字段值
field.set(personInstance, "New Name"); // 设置字段值

4. 调用方法

可以通过反射调用类的方法:

Class<?> clazz = Person.class;
Method method = clazz.getMethod("sayHello");
method.invoke(personInstance);Method methodWithArgs = clazz.getMethod("greet", String.class);
methodWithArgs.invoke(personInstance, "World");

5. 获取构造函数

可以使用反射获取和调用构造函数:

Class<?> clazz = Person.class;
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("John", 30);

6. 获取接口和父类

可以使用反射获取类实现的接口和父类:

Class<?> clazz = Person.class;// 获取所有接口
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> i : interfaces) {System.out.println("Interface: " + i.getName());
}// 获取父类
Class<?> superClass = clazz.getSuperclass();
System.out.println("Superclass: " + superClass.getName());

以下是一个完整的示例,展示了如何使用反射来创建对象、访问字段和调用方法:

实例

**import** java.lang.reflect.Constructor;
**import** java.lang.reflect.Field;
**import** java.lang.reflect.Method;**public** **class** ReflectionExample {**public** **static** **void** main(String[] args) **throws** Exception {*// 获取 Class 对象*Class<?> clazz = Person.**class**;*// 创建对象*Constructor<?> constructor = clazz.getConstructor(String.**class**, **int**.**class**);Object person = constructor.newInstance("John", 30);*// 访问字段*Field nameField = clazz.getDeclaredField("name");nameField.setAccessible(**true**);System.out.println("Name: " + nameField.get(person));*// 修改字段*nameField.set(person, "Doe");System.out.println("Updated Name: " + nameField.get(person));*// 调用方法*Method greetMethod = clazz.getMethod("greet", String.**class**);greetMethod.invoke(person, "World");}
}**class** Person {**private** String name;**private** **int** age;**public** Person(String name, **int** age) {**this**.name = name;**this**.age = age;}**public** **void** greet(String message) {System.out.println(name + " says: " + message);}
}

编译执行以上代码,输出结果为:

Name: John
Updated Name: Doe
Doe says: World

java.lang.reflect

java.lang.reflect 是 Java 反射机制的核心包,提供了操作类及其成员(字段、方法、构造函数等)的类和接口。通过这些 API,开发者可以在运行时动态地查询和修改类的结构。

img

以下是 java.lang.reflect 包中的主要类和接口的详细介绍:

1. Class

  • 功能:表示类的对象,提供了获取类信息的方法,如字段、方法、构造函数等。

  • 主要方法

    • getFields():获取所有公共字段。
    • getDeclaredFields():获取所有声明的字段,包括私有字段。
    • getMethods():获取所有公共方法。
    • getDeclaredMethods():获取所有声明的方法,包括私有方法。
    • getConstructors():获取所有公共构造函数。
    • getDeclaredConstructors():获取所有声明的构造函数,包括私有构造函数。
    • getSuperclass():获取类的父类。
    • getInterfaces():获取类实现的所有接口。

2. Field

  • 功能:表示类的字段(属性),提供了访问和修改字段值的方法。

  • 主要方法

    • get(Object obj):获取指定对象的字段值。
    • set(Object obj, Object value):设置指定对象的字段值。
    • getType():获取字段的数据类型。
    • getModifiers():获取字段的修饰符(如 public、private)。

3. Method

  • 功能:表示类的方法,提供了调用方法的能力。

  • 主要方法

    • invoke(Object obj, Object... args):调用指定对象的方法。
    • getReturnType():获取方法的返回类型。
    • getParameterTypes():获取方法的参数类型。
    • getModifiers():获取方法的修饰符(如 public、private)。

4. Constructor

  • 功能:表示类的构造函数,提供了创建对象的能力。

  • 主要方法

    • newInstance(Object... initargs):创建一个新实例,使用指定的构造函数参数。
    • getParameterTypes():获取构造函数的参数类型。
    • getModifiers():获取构造函数的修饰符(如 public、private)。

示例代码

以下是使用 java.lang.reflect 包进行反射操作的示例:

实例

**import** java.lang.reflect.Field;
**import** java.lang.reflect.Method;
**import** java.lang.reflect.Constructor;**public** **class** ReflectionExample {**public** **static** **void** main(String[] args) **throws** Exception {*// 获取 Class 对象*Class<?> clazz = Car.**class**;*// 创建 Car 对象*Constructor<?> constructor = clazz.getConstructor(String.**class**, **int**.**class**);Object car = constructor.newInstance("Toyota", 2020);*// 访问和修改字段*Field modelField = clazz.getDeclaredField("model");Field yearField = clazz.getDeclaredField("year");
​    
​    *// 设置字段为可访问(如果字段是私有的)*
​    modelField.setAccessible(**true**);
​    yearField.setAccessible(**true**);
​    
​    *// 打印原始字段值*System.out.println("Original Model: " + modelField.get(car));System.out.println("Original Year: " + yearField.get(car));
​    
​    *// 修改字段值*
​    modelField.set(car, "Honda");
​    yearField.set(car, 2024);
​    
​    *// 打印修改后的字段值*System.out.println("Updated Model: " + modelField.get(car));System.out.println("Updated Year: " + yearField.get(car));
​    
​    *// 调用方法*Method startMethod = clazz.getMethod("start");
​    startMethod.invoke(car);}
}**class** Car {**private** String model;**private** **int** year;**public** Car(String model, **int** year) {**this**.model = model;**this**.year = year;}**public** **void** start() {System.out.println("The " + model + " car of year " + year + " is starting.");}
}

编译执行以上代码,输出结果为:

Original Model: Toyota
Original Year: 2020
Updated Model: Honda
Updated Year: 2024
The Honda car of year 2024 is starting.
r;}**public** **void** start() {System.out.println("The " + model + " car of year " + year + " is starting.");}
}

编译执行以上代码,输出结果为:

Original Model: Toyota
Original Year: 2020
Updated Model: Honda
Updated Year: 2024
The Honda car of year 2024 is starting.

相关文章:

Java 反射(Reflection)

Java 反射&#xff08;Reflection&#xff09; Java 反射&#xff08;Reflection&#xff09;是一个强大的特性&#xff0c;它允许程序在运行时查询、访问和修改类、接口、字段和方法的信息。反射提供了一种动态地操作类的能力&#xff0c;这在很多框架和库中被广泛使用&#…...

Python爬取机车网车型数据并存入Mysql数据库

结果展示&#xff08;文末附完整代码&#xff09;&#xff1a; 一、引言 在当今数字化时代&#xff0c;数据对于各个领域的重要性不言而喻。对于机车行业而言&#xff0c;获取丰富的机车品牌、车型及详细信息数据&#xff0c;能够为市场分析、消费者研究等提供有力支持。本文将…...

fpga 时序分析基础

目录 触发器的动态参数 同步时序电路分析 1. 时钟脉冲的特性 2. 同步时序电路分析 Timing Analyzer的应用 异步时序与亚稳态问题 时序分析就是对时序电路进行时序检查&#xff0c;通过分析电路中所有寄存器之间的路径延迟以检查电路的传输延迟是否会导致触发器的建立时间…...

python学习——二维列表的列表生成式

二维列表的列表生成式允许你生成一个列表&#xff0c;其中每个元素本身也是一个列表。这在处理矩阵或表格数据时非常有用。 以下是如何使用列表生成式来创建二维列表的示例&#xff1a; 文章目录 基本语法示例1. 创建一个 3x3 的单位矩阵2. 创建一个 4x4 的乘法表3. 创建一个 …...

【错误❌】——槽函数定义好但未初始化

public slots:void onClose(); 初始化即可成功&#xff1a;...

OpenCV相机标定与3D重建(6)将3D物体点投影到2D图像平面上函数projectPoints()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::fisheye::projectPoints 是 OpenCV 库中用于鱼眼镜头模型的函数&#xff0c;它将3D物体点投影到2D图像平面上。这个函数对于模拟或者理解鱼眼…...

【Linux】剧幕中的灵魂更迭:探索Shell下的程序替换

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 一念既出&#xff0c;万山无阻 目录 &#x1f4d6;一、进程程序替换 1.替换的演示 ❓替换与执行流 ❓程序替换≠进程替换 2.替换的原理 …...

38 基于单片机的宠物喂食(ESP8266、红外、电机)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STC89C52单片机&#xff0c;采用L298N驱动连接P2.3和P2.4口进行电机驱动&#xff0c; 然后串口连接P3.0和P3.1模拟ESP8266&#xff0c; 红外传感器连接ADC0832数模转换器连接单片机的P1.0~P1.…...

Unity中的数学应用 之 角色移动中单位化向量的妙用 (小学难度)

最近准备从简单到困难跟几个教程用以加强自己的业务能力&#xff0c;相信很多小伙伴都做过胡闹厨房这一个案例&#xff0c;其实这个案例比较初级&#xff0c;但是也包含了很多平常可能注意不到小细节&#xff0c;所以我就以它为举例&#xff0c;拓展其中的数学知识 CodeMonkey教…...

设置ip和代理DNS的WindowsBat脚本怎么写?

今天分享一个我们在工作时&#xff0c;常见的在Windows中通过批处理脚本&#xff08;.bat 文件&#xff09;来设置IP地址、代理以及DNS 相关配置的示例&#xff0c;大家可以根据实际需求进行修改调整。 一、设置静态IP地址脚本示例 以下脚本用于设置本地连接&#xff08;你可…...

字符串分割转换(Java Python JS C++ C )

题目描述 给定一个非空字符串S,其被N个‘-’分隔成N+1的子串,给定正整数K,要求除第一个子串外,其余的子串每K个字符组成新的子串,并用‘-’分隔。 对于新组成的每一个子串,如果它含有的小写字母比大写字母多,则将这个子串的所有大写字母转换为小写字母; 反之,如果它…...

【Maven】项目创建

3. Maven的应用 本章主要内容&#xff1a; 使用 Maven 创建 JavaSE 项目使用 Maven 创建 JavaWeb 项目&#xff0c;在本地部署 Tomcat 测试导入 Maven 项目 3.1 基于Maven开发JavaSE的项目 3.1.1 流程 1、File—>new—>Project—>Empty Project Location&#xff1…...

number的++和--运算 C#

number10 请计算num number --number - number number就是先对number运算&#xff0c;然后再给number赋值--number 先给number赋值&#xff0c;再拿来运算 using System;class Program {static void Main(string[] args){int number 10;int a, b, c, number1, number2;…...

浅谈网络 | 应用层之HTTPS协议

目录 对称加密非对称加密数字证书HTTPS 的工作模式重放与篡改 使用 HTTP 协议浏览新闻虽然问题不大&#xff0c;但在更敏感的场景中&#xff0c;例如支付或其他涉及隐私的数据传输&#xff0c;就会面临巨大的安全风险。如果仍然使用普通的 HTTP 协议&#xff0c;数据在网络传输…...

2、Three.js初步认识场景Scene、相机Camera、渲染器Renderer三要素

三要素之间关系&#xff1a; 有了虚拟场景Scene&#xff0c;相机录像Camera&#xff0c;在相机小屏幕上看到的Renderer Scene当前空间 Mesh人在场景 Camera相机录像 Renderer显示器上 首先先描述下Scene&#xff1a; 这个场景为三要素之一&#xff0c;一切需要展示的东西都需…...

Deepwave 声波正演和弹性波正演

Deepwave Deepwave 调用 scalar 方法实现声波和弹性波正演。 ######## 声波正演 ###################### import torch import numpy as np import deepwave from deepwave import scalardevice torch.device(cuda if torch.cuda.is_available()else cpu)## Set observation…...

【WRF-Urban】多层建筑能源参数化模型概述:原理

【WRF-Urban】多层建筑能源参数化模型概述&#xff1a;原理 1 概述1.1 原理1.2 使用步骤 2参考 多层建筑能源参数化&#xff08;Multi-layer Building Energy Parameterization, BEP&#xff09;模型是一种用于模拟城市环境中多层建筑群的能量交换和微气候影响的参数化模型。该…...

基于Qt实现的自定义树结构容器:设计与应用

在Qt框架中&#xff0c;尽管其提供了许多强大的容器类&#xff08;如 QList, QMap, QTreeWidget 等&#xff09;&#xff0c;但缺少一个通用的、灵活的树结构容器&#xff0c;直接支持多层级数据管理。为了满足这些需求&#xff0c;本文设计并实现了一个可复用的自定义树结构容…...

网络命令Linux

目录 一&#xff0c;Linux 二&#xff0c;CMD 一&#xff0c;Linux ping www.baidu.com 测试联网 -c 2 次数&#xff0c;ping几次 &#xff0c; -i 间隔 -W timeout 超时时间&#xff0c;等待响应的超时时间 ss -lntup |grep -w 22 netstat -lntup |grep -w 22 lsof -i:22 ls…...

简单的Activiti Modoler 流程在线编辑器

简单的Activiti Modoler 流程在线编辑器 1.需求 我们公司使用的流程是activiti5.22.0&#xff0c;版本有些老了&#xff0c;然后使用的编辑器都是eclipse的流程编辑器插件&#xff0c;每次编辑流程需要打开eclipse进行编辑&#xff0c;然后再导入到项目里面&#xff0c;不是特…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

《Docker》架构

文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器&#xff0c;docker&#xff0c;镜像&#xff0c;k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...