java怎么使用反射给对象属性赋值
来源:亿速云
时间:2024-04-21 12:00:36 467浏览 收藏
欢迎各位小伙伴来到golang学习网,相聚于此都是缘哈哈哈!今天我给大家带来《java怎么使用反射给对象属性赋值》,这篇文章主要讲到等等知识,如果你对文章相关的知识非常感兴趣或者正在自学,都可以关注我,我会持续更新相关文章!当然,有什么建议也欢迎在评论留言提出!一起学习!
前言
最近项目中遇到一个问题,就是能实现一个类将以后的多语都进行转换的通用方法,根据这个需求,决定使用反射实现,根据反射给对象属性设置属性值,下面是使用反射实现对对象属性值进行设置的方法
方法1:这里使用了Field的set方的 Field 属性,然后设置可见性,然后设置了一个值,最后打印
// 给变量赋值 给object对象的某个字段赋值
f.set(object, value);
//拿到了Field类的实例后就可以调用其中的方法了
//方法:get(Object obj) 返回指定对象obj上此 Field 表示的字段的值
package com.example.reflectiondemo; import java.lang.reflect.Field; /** * @program my-project-model * @description: * @author: lee * @create: 2023/01/04 19:52 */ public class ReflectMain { private String readOnly; public String getReadOnly() { return readOnly; } public void setReadOnly(String readOnly) { System.out.println("set"); this.readOnly = readOnly; } public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { ReflectMain t = new ReflectMain(); Field f = t.getClass().getDeclaredField("readOnly"); f.setAccessible(true); f.set(t, "test"); System.out.println(t.getReadOnly()); } }
方法2:使用invoke方法
package com.example.reflectiondemo; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @program my-project-model * @description: * @author: lee * @create: 2023/01/04 19:52 */ public class ReflectMain { private String readOnly; public String getReadOnly() { return readOnly; } public void setReadOnly(String readOnly) { System.out.println("set"); this.readOnly = readOnly; } // public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { // ReflectMain t = new ReflectMain(); // Field f = t.getClass().getDeclaredField("readOnly"); // f.setAccessible(true); // f.set(t, "test"); // System.out.println(t.getReadOnly()); // // } public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { ReflectMain t = new ReflectMain(); Method setReadOnly = t.getClass().getMethod("setReadOnly", String.class); String s = "test2"; setReadOnly.invoke(t, s); System.out.println(t.getReadOnly()); } }
由此可见,使用反射我们能给很容易的给各个属性进行设置,即使是private的属性我们也能很轻松的设置属性值,下面利用这个demo例子,就设置了我们的最初的功能。
总结:
也就是说,第一种方法,没有调用属性的set方法就完成了赋值,
但是第二种方法,是通过调用属性的set方法来完成赋值。
所以,如果想在程序中改变程序的属性的值的同时还想做一些额外的事情,可以将这些事情写到set方法中并使用第二种方法
public class MultiLangContentUtil { /** * 从PO查询数据赋值到DTO * 注意!!这里的多语字段根据 * 简体中文的变量名 英文名和繁体名需要根据规则进行 指定 * 规则如下 * 英文名=简体中文名2 * 繁体名=简体中文名3 * * @param targetPO 数据库中查询出的数据 * @param targetDTO 将要转换的对象DTO * @param targetMultiName 需要展示的多语字段 * @throws NoSuchFieldException * @throws IllegalAccessException */ public static void setMultiLangDTOName(Object targetPO, Object targetDTO, String targetMultiName) { try { String locale = MultiLangContentUtil.getLocale(); Class> targetDTOClass = targetDTO.getClass(); Class> targetPOClass = targetPO.getClass(); //这里是将targetMultiName进行展示 Field declaredFieldDTO = targetDTOClass.getDeclaredField(targetMultiName); declaredFieldDTO.setAccessible(true); switch (locale) { case ZH_CN: //获取PO的值 Field declaredFieldPO = targetPOClass.getDeclaredField(targetMultiName); //获取DTO对象 declaredFieldPO.setAccessible(true); //对DTO根据PO进行设置 declaredFieldDTO.set(targetDTO, declaredFieldPO.get(targetPO)); break; case EN_US: //获取PO的值 Field declaredFieldPO2 = targetPOClass.getDeclaredField(targetMultiName + 2); //获取DTO对象 declaredFieldPO2.setAccessible(true); //对DTO根据PO进行设置 declaredFieldDTO.set(targetDTO, declaredFieldPO2.get(targetPO)); break; case ZH_TW: //获取PO的值 Field declaredFieldPO3 = targetPOClass.getDeclaredField(targetMultiName + 3); //获取DTO对象 declaredFieldPO3.setAccessible(true); //对DTO根据PO进行设置 declaredFieldDTO.set(targetDTO, declaredFieldPO3.get(targetPO)); break; default: break; } //防止没有抽取多语的情况下没有参照返回,默认情况下设置中文 if (StringUtils.isBlank((String) declaredFieldDTO.get(targetDTO))) { //获取PO的值 Field declaredFieldPO = targetPOClass.getDeclaredField(targetMultiName); //获取DTO对象 declaredFieldPO.setAccessible(true); //对DTO根据PO进行设置 declaredFieldDTO.set(targetDTO, declaredFieldPO.get(targetPO)); } } catch (NoSuchFieldException e) { log.error("查询当前字段--->{}不存在{},", targetMultiName, e); } catch (IllegalAccessException e) { log.error("查询字段--->{}多语时发生非法状态异常{},", targetMultiName, e); } catch (Exception e) { log.error("查询字段{}多语时发生错误{},", targetMultiName, e); } catch (Throwable throwable) { log.error("查询多语言字段{}发生未知错误{}", targetMultiName, ThrowableUtil.stackTraceToString(throwable)); } } /** * 更新多语字段 * * @param targetDTO 需要转换的字段 * @param targetPO 数据库PO * @param fieldName 多语字段 * @param MultiLangSize 多语字段的数量 */ public static void updateMultiLang(Object targetDTO, Object targetPO, String fieldName, Integer MultiLangSize) { try { Class> targetDTOClass = targetDTO.getClass(); Class> targetPOClass = targetPO.getClass(); Field dtoClassField = targetDTOClass.getDeclaredField(fieldName); dtoClassField.setAccessible(true); if (StringUtils.isNotBlank((String) dtoClassField.get(targetDTO))) { Field poClassField = targetPOClass.getDeclaredField(fieldName); poClassField.setAccessible(true); poClassField.set(targetPO, dtoClassField.get(targetDTO)); } for (int i = 2; i <= MultiLangSize; i++) { Field dtoClassField2 = targetDTOClass.getDeclaredField(fieldName + i); dtoClassField2.setAccessible(true); if (StringUtils.isNotBlank((String) dtoClassField2.get(targetDTO))) { Field poClassField2 = targetPOClass.getDeclaredField(fieldName + i); poClassField2.setAccessible(true); poClassField2.set(targetPO, dtoClassField2.get(targetDTO)); } } } catch (NoSuchFieldException e) { log.error("更新当前字段--->{}不存在{},", fieldName, e); } catch (IllegalAccessException e) { log.error("更新字段--->{}多语时发生非法状态异常{},", fieldName, e); } catch (Exception e) { log.error("更新字段{}多语时发生错误{},", fieldName, e); } catch (Throwable throwable) { log.error("更新多语言字段{}发生未知错误{}", fieldName, ThrowableUtil.stackTraceToString(throwable)); } } /** * 获取本地的语言,默认中文 * en_US 英文 * zh_CN 简体中文 * zh_TW 繁体中文 * * @return */ public static final String getLocale() { String locale = InvocationInfoProxy.getLocale(); return StringUtils.isEmpty(locale) ? "zh_CN" : locale; } }
这个工具类的核心思想就是
使用Field的get方法获取属性值
Field的set方法设置属性
// 给变量赋值 给object对象的某个字段赋值
f.set(object, value);
//拿到了Field类的实例后就可以调用其中的方法了
//方法:get(Object obj) 返回指定对象obj上此 Field 表示的字段的值
理论要掌握,实操不能落!以上关于《java怎么使用反射给对象属性赋值》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
469 收藏
-
236 收藏
-
396 收藏
-
341 收藏
-
200 收藏
-
149 收藏
-
122 收藏
-
408 收藏
-
373 收藏
-
158 收藏
-
346 收藏
-
184 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习