java反射机制及beanUtils的实现原理

目录

1.反射机制说明

2.VO,DTO,PO的说明

3.beanUtils的实现原理

4.beanUtils的简单示例


1.反射机制说明

Java的反射机制允许程序在运行时检查和操作类、方法、字段等结构。通过反射,可以动态地创建对象、调用方法、获取/设置字段的值,而无需在编译时确定这些操作。反射的核心类是java.lang.reflect包中的MethodFieldConstructor等。使用反射需要注意性能开销和安全性问题。

获取类的Class对象

Class<?> clazz = MyClass.class;

 实例化对象

MyClass myObject = (MyClass) clazz.getDeclaredConstructor().newInstance();

 获取和调用方法

Method method = clazz.getDeclaredMethod("methodName", parameterTypes);
method.setAccessible(true); // 如果方法是private的,需要设置accessible为true
Object result = method.invoke(myObject, args);

 获取和设置字段值

Field field = clazz.getDeclaredField("fieldName");
field.setAccessible(true); // 如果字段是private的,需要设置accessible为true
Object value = field.get(myObject);
field.set(myObject, newValue);

操作构造函数

Constructor<?> constructor = clazz.getDeclaredConstructor(parameterTypes);
constructor.setAccessible(true); // 如果构造函数是private的,需要设置accessible为true
MyClass myObject = (MyClass) constructor.newInstance(args);

2.VO,DTO,PO的说明

VO(Value Object)值对象

VO就是展示用的数据,不管展示方式是网页,还是客户端,还是APP,只要是这个东西是让人看到的,这就叫VO,这个大家都很理解,反正就是我们的接口返回给前端的对象都是用VO来返回,跟DTO不一样的是,VO是我们返回给前端,DTO是我们从前端接收的时候用的,即一个是入参,一个是返回结果

DTO(Data Transfer Object)数据传输对象

这个传输通常指的前后端之间的传输

DTO是一个比较特殊的对象,他有两种存在形式:

一种是前端和后端交互所使用的对象,另一种是微服务之间的一种传输对象,我们一般也是用DTO来进行传输

PO(Persistant Object)持久对象

PO比较好理解,简单说PO就是数据库中的记录,一个PO的数据结构对应着库中表的结构,表中的一条记录就是一个PO对象,通常PO里面除了get,set之外没有别的方法,对于PO来说,数量是相对固定的,一定不会超过数据库表的数量,等同于BO,这俩概念是一致的

3.beanUtils的实现原理

在后端的各个层中进行数据传输时,经常使用beanUtils进行bean的拷贝,其实现原理就是通过java的放射机制实现。

package org.springframework.beans;private static void copyProperties(Object source, Object target, @Nullable Class<?> editable, @Nullable String... ignoreProperties) throws BeansException {Assert.notNull(source, "Source must not be null");Assert.notNull(target, "Target must not be null");Class<?> actualEditable = target.getClass();if (editable != null) {if (!editable.isInstance(target)) {throw new IllegalArgumentException("Target class [" + target.getClass().getName() + "] not assignable to Editable class [" + editable.getName() + "]");}actualEditable = editable;}PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);List<String> ignoreList = ignoreProperties != null ? Arrays.asList(ignoreProperties) : null;PropertyDescriptor[] var7 = targetPds;int var8 = targetPds.length;for(int var9 = 0; var9 < var8; ++var9) {PropertyDescriptor targetPd = var7[var9];Method writeMethod = targetPd.getWriteMethod();if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());if (sourcePd != null) {Method readMethod = sourcePd.getReadMethod();if (readMethod != null) {ResolvableType sourceResolvableType = ResolvableType.forMethodReturnType(readMethod);ResolvableType targetResolvableType = ResolvableType.forMethodParameter(writeMethod, 0);boolean isAssignable = !sourceResolvableType.hasUnresolvableGenerics() && !targetResolvableType.hasUnresolvableGenerics() ? targetResolvableType.isAssignableFrom(sourceResolvableType) : ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType());if (isAssignable) {try {if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {readMethod.setAccessible(true);}Object value = readMethod.invoke(source);if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {writeMethod.setAccessible(true);}writeMethod.invoke(target, value);} catch (Throwable var18) {throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", var18);}}}}}}}

4.beanUtils的简单示例

public class BeanToolUtils {public static void copy(Object source, Object target) throws Exception {Class<?> sourceClass = source.getClass();Class<?> targeteClass = target.getClass();Field[] fields = targeteClass.getDeclaredFields();// 输出字段信息for (Field field : fields) {String name = field.getName();if ("serialVersionUID".equals(name)) {continue;}String getterName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);String setterName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);Method getMethod = sourceClass.getMethod(getterName);if(!ObjectUtils.isEmpty(getMethod)){Object val = getMethod.invoke(source);Method setMethod = targeteClass.getMethod(setterName,field.getType());setMethod.invoke(target, val);}}}
}

说明:

获取目标bean的class对象,通过class对象获取目标bean的所有属性,循环属性信息,获取属性的get和set方法,执行来源bean的get方法获取属性值,执行目标bean的set方法,设置属性值,完成bean的赋值操作。

参照:

Java 中的反射机制(两万字超全详解)_java反射-CSDN博客

原来不止有 BeanUtils 啊,来看看更优秀的 MapStruct 吧

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

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

相关文章

LLM主要类别架构

LLM主要类别架构介绍 LLM主要类别 LLM本身基于transformer架构。自2017年&#xff0c;attention is all you need诞生起&#xff0c;transformer模型为不同领域的模型提供了灵感和启发。基于原始的Transformer框架&#xff0c;衍生出了一系列模型&#xff0c;一些模型仅仅使用e…

分享一篇压箱底的融合通信技术方案

随着信息技术的发展和通信行业的变革&#xff0c;传统的电信、互联网和移动通信等领域开始融合&#xff0c;形成了融合通信的概念。借助5G、物联网、云计算和大数据等新技术的不断涌现&#xff0c;融合通信技术迎来大发展&#xff0c;在各行各业中有重要应用&#xff0c;融合通…

机床测头助力零部件自动化生产

随着国内制造业朝着自动化、智能化方向快速发展&#xff0c;产品质量检测也由过去的脱机、人工检测方式向在线自动检测转变&#xff0c;作为在线检测的重要工具&#xff0c;机床测头在制造业自动化生产过程中发挥着非常重要的作用。 1.自动化检测与防呆&#xff1a;机床测头可以…

Python面试宝典:Python中与代码性能优化相关的面试笔试题(1000加面试笔试题助你轻松捕获大厂Offer)

Python面试宝典:1000加python面试题助你轻松捕获大厂Offer【第二部分:Python高级特性:第二十一章:代码性能优化:第一节:代码性能优化】 第二十一章:代码性能优化第一节:代码性能优化1. 使用内置数据类型2. 利用列表推导式和生成器表达式3. 使用局部变量4. 减少函数调用…

102.网络游戏逆向分析与漏洞攻防-ui界面的设计-反隐身功能的界面设计与实现(有不使用MFC生成,自己手写代码创建复选框与事件的例子)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

经典JS面试题——数组去重

文章目录 一、双指针二、filter方法三、includes四、indexOf五、reduce()六、set 一、双指针 基本思想&#xff1a;遍历数组&#xff0c;两层for循环比较元素是否相等&#xff0c;相等就删除重复元素。 代码如下 for(var i0;i<arr.length;i) {for(var ji1;j<arr.length…

Keras深度学习框架实战(5):KerasNLP使用GPT2进行文本生成

1、KerasNLP与GPT2概述 KerasNLP的GPT2进行文本生成是一个基于深度学习的自然语言处理任务&#xff0c;它利用GPT-2模型来生成自然流畅的文本。以下是关于KerasNLP的GPT2进行文本生成的概述&#xff1a; GPT-2模型介绍&#xff1a; GPT-2&#xff08;Generative Pre-trained …

EMQX Enterprise 5.7 发布:新增会话持久化、消息 Schema 验证、规则引擎调试与追踪功能

EMQX Enterprise 5.7.0 版本现已正式发布&#xff01; 在这个版本中&#xff0c;我们引入了一系列新的功能和改进&#xff0c;包括会话持久化、消息 Schema 验证、规则引擎调试与追踪测试等功能。此外&#xff0c;新版本还进行了多项改进以及 BUG 修复&#xff0c;进一步提升了…

项目-双人五子棋对战: websocket的讲解与使用 (1)

项目介绍 接下来, 我们将制作一个关于双人五子棋的项目, 话不多说先来理清一下需求. 1.用户模块 用户的注册和登录 管理用户的天梯分数, 比赛场数, 获胜场数等信息. 2.匹配模块 依据用户的天梯积分, 实现匹配机制. 3.对战模块 把两个匹配到的玩家放到同一个游戏房间中, 双方通…

Linux_应用篇(15) 输入设备应用编程

本章学习输入设备的应用编程&#xff0c;首先要知道什么是输入设备&#xff1f; 输入设备其实就是能够产生输入事件的设备就称为输入设备&#xff0c; 常见的输入设备包括鼠标、键盘、触摸屏、按钮等等&#xff0c;它们都能够产生输入事件&#xff0c;产生输入数据给计算机系统…

文件夹加密软件哪个好用?文件加密的4个必备方法(2024)

如果您的电脑上有重要的个人或商业内容&#xff08;例如知识产权&#xff09;&#xff0c;您可能想知道如何确保数据的安全。如果笔记本电脑丢失或被盗&#xff0c;他人可能会访问硬盘驱动器的内容&#xff0c;从而获取到您的个人隐私信息。因此&#xff0c;通过文件夹加密软件…

水电站生产指挥调度系统方案

一、方案背景 在碧波荡漾的大江大河之上&#xff0c;巍然屹立着一座座水电站&#xff0c;它们如同一个个巨人在默默地守护着我们的家园。在这些建设者的辛勤耕耘下&#xff0c;水电站在保障国家能源安全、优化能源结构以及减少环境污染等方面发挥着重要作用。 然而&#xff0c…

vue开发网站-使用插件element、vant 遇到的问题

1. js把两个字符串放进一个另字符串里&#xff0c;用逗号分隔 let string1 "Hello"; let string2 "World"; let result ${string1},${string2}; console.log(result); // 输出: Hello,World2.js将字符串转为数组 const str "Hello, world!"…

深入探索 Linux 命令之 AWK:文本处理的神兵利器

深入探索 Linux 命令之 AWK&#xff1a;文本处理的神兵利器 在 Linux 系统中&#xff0c;文本处理是日常运维和数据分析中不可或缺的一部分。而 awk 命令&#xff0c;作为 Linux 文本处理三剑客之一&#xff08;另外两个是 sed 和 grep&#xff09;&#xff0c;以其强大的文本…

跨越百亿营收的今世缘,全国化进程仍挑战重重?

当前&#xff0c;白酒市场正在经历一场深度调整&#xff0c;随着存量时代到来&#xff0c;白酒品牌地位的更替和竞争格局的重构已经展开。这一背景下&#xff0c;今世缘等地方性酒企也正在凭借对区域市场的深耕&#xff0c;展现出较快的成长速度&#xff0c;并希望能借此占领市…

搭建一个基于主流技术Spring Boot 2 + Vue 3 + Ant Design Vue的技术框架的简要步骤

搭建一个基于主流技术Spring Boot 2 Vue 3 Ant Design Vue的技术框架涉及前后端分离的开发模式。以下是一个简化的步骤指南&#xff0c;用于帮助你开始这个项目&#xff1a; 1. 后端&#xff08;Spring Boot 2&#xff09; 1.1 初始化项目 使用Spring Initializr&#xff08;…

超强算力 Orange Pi Kunpeng Pro 开发板基础测评与体验

目录 开箱体验资源简介系统启动连接网络登录系统通过桌面登录通过串口登录通过 SSH 登录配置散热风扇 算力测试MNIST示例MBNET示例 体验总结 大家好&#xff0c;我是 Hello 阿尔法&#xff0c;有幸接到 CSDN 的邀请参与 Orange Pi Kunpeng Pro 开发板的测评活动&#xff0c;本文…

【Redis】redis高阶-使用zset实现延时队列

Hi,大家好&#xff0c;我是抢老婆酸奶的小肥仔。 最近在使用redis时&#xff0c;就想能不能用其实现消息队列&#xff1f;也在网上看了下其他小伙伴写的实现&#xff0c;结合自身业务实现了如下消息队列&#xff0c;希望对大家有用。 废话不多说&#xff0c;直接开撸。 1、为…

The minCompileSdk (34) specified in adependency‘s AAR metadata

新版AS新增Activity的时候&#xff0c;数据结构是&#xff1a;import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInse…

hmcode硬件编程1

在/home/golemon/hmcode/applications/sample/wifi-iot/app内创建文件夹。 这里创建了d_6_3文件夹 . ├── BUILD.gn ├── d_6_3 │ ├── BUILD.gn │ └── lab.c ├── demolink │ ├── BUILD.gn │ └── helloworld.c ├── iothardware │ ├── B…