java反射机制给实体类相同字段自动赋值实例
作者:The best are water 发布时间:2023-11-25 19:52:29
标签:java,反射,实体类,字段,赋值
一、封装一个工具类
1、简易版
package net.aexit.construct.acceptance.websky.utils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class ClassReflection {
/**
* @param class1 用于赋值的实体类
* @param class2 需要待赋值的实体类
* 描述:反射实体类赋值
*/
public static void reflectionAttr(Object class1,Object class2) throws Exception{
Class clazz1 = class1.getClass();
Class clazz2 = class2.getClass();
// 获取两个实体类的所有属性
Field[] fields1 = clazz1.getDeclaredFields();
Field[] fields2 = clazz2.getDeclaredFields();
// 遍历class1Bean,获取逐个属性值,然后遍历class2Bean查找是否有相同的属性,如有相同则赋值
for (Field f1 : fields1) {
if(f1.getName().equals("id"))
continue;
//设置访问权限
f1.setAccessible(true);
Object value = f1.get(class1);
for (Field f2 : fields2) {
if(f1.getName().equals(f2.getName())){
//设置访问权限
f2.setAccessible(true);
f2.set(class2,value);
}
}
}
}
}
2、复杂版
package net.utils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class ClassReflection {
/**
* @param class1 用于赋值的实体类
* @param class2 需要待赋值的实体类
* 描述:反射实体类赋值
*/
public static void reflectionAttr(Object class1,Object class2) throws Exception{
Class clazz1 = Class.forName(class1.getClass().getName());
Class clazz2 = Class.forName(class2.getClass().getName());
// 获取两个实体类的所有属性
Field[] fields1 = clazz1.getDeclaredFields();
Field[] fields2 = clazz2.getDeclaredFields();
ClassReflection cr = new ClassReflection();
// 遍历class1Bean,获取逐个属性值,然后遍历class2Bean查找是否有相同的属性,如有相同则赋值
for (Field f1 : fields1) {
if(f1.getName().equals("id"))
continue;
Object value = cr.invokeGetMethod(class1 ,f1.getName(),null);
for (Field f2 : fields2) {
if(f1.getName().equals(f2.getName())){
Object[] obj = new Object[1];
obj[0] = value;
cr.invokeSetMethod(class2, f2.getName(), obj);
}
}
}
}
/**
*
* 执行某个Field的getField方法
* @param clazz 类
* @param fieldName 类的属性名称
* @param args 参数,默认为null
* @return
*/
public Object invokeGetMethod(Object clazz, String fieldName, Object[] args) {
String methodName = fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);
Method method = null;
try
{
method = Class.forName(clazz.getClass().getName()).getDeclaredMethod("get" + methodName);
return method.invoke(clazz);
}
catch (Exception e)
{
e.printStackTrace();
return "";
}
}
/**
*
* 执行某个Field的setField方法
* @param clazz 类
* @param fieldName 类的属性名称
* @param args 参数,默认为null
* @return
*/
public Object invokeSetMethod(Object clazz, String fieldName, Object[] args)
{
String methodName = fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);
Method method = null;
try
{
Class[] parameterTypes = new Class[1];
Class c = Class.forName(clazz.getClass().getName());
Field field = c.getDeclaredField(fieldName);
parameterTypes[0] = field.getType();
method = c.getDeclaredMethod("set" + methodName,parameterTypes);
return method.invoke(clazz,args);
}
catch (Exception e)
{
e.printStackTrace();
return "";
}
}
//map转换为json字符串
public static String hashMapToJson(HashMap map) {
String string = "{";
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry e = (Map.Entry) it.next();
string += "'" + e.getKey() + "':";
string += "'" + e.getValue() + "',";
}
string = string.substring(0, string.lastIndexOf(","));
string += "}";
return string;
}
}
二、调用工具类
ClassReflection.reflectionAttr(class1, class2);
三、赋值完成
注意:
1、id不赋值,主要给数据库两张表赋值,比如当前表和历史表,把当前表的相同字段的值赋值给历史表
2、简单版设置private修饰的字段可以被访问
补充知识:利用java反射原理给实体类注值
写一个通用java注值的方法,使用泛型T,将其封装在DbHelp中(相信DbHelper不用我解释是什么),使dao调用直接获取所需要的对象,也正应用了我们java面向对象的思想
public static<T> T getBean(String sql,Class<T> clazz){
Method[] ms=clazz.getDeclaredMethods();
T t=null;
try {
t=clazz.newInstance();
for (Method m : ms) {
String mn=m.getName();
if(mn.startsWith("set")){
Object obj=map.get((mn.replace("set", "").toUpperCase()));//取到set方法对应数据库字段的值
String pt=m.getParameterTypes()[0].toString();//取到set方法的参数类型
if(obj!=null){
if(pt.endsWith("int")||pt.endsWith("Integer")){
m.invoke(t, ((BigDecimal)obj).intValue());
}else if(pt.endsWith("Double")||pt.endsWith("double")){
m.invoke(t, ((BigDecimal)obj).doubleValue());
}else if(pt.endsWith("Date")){
m.invoke(t, (Timestamp)obj);
}else {
m.invoke(t, obj);
}
}
}
}
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return t;
}
来源:https://blog.csdn.net/kaixuansui/article/details/88942230
0
投稿
猜你喜欢
- 用了MyBatis的同行,应该见过foreach,它一般是这样用的:<select id="foreachTest"
- C# 关于Invoke首先说下,invoke和begininvoke的使用有两种情况:control中的invoke、begininvoke
- 0 实验环境在Android Studio中进行有关代码的编写和界面效果展示。SQLite数据库的图形化工具SQLiteStudio下载网址
- 工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。工
- tokentoken的意思是“令牌”,是用户身份的验证方式,最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳
- 下载maven 解压路径: 打开环境变量:右键此电脑-属性-高级系统设置-高级-环境变量添加以下系统变量:测试:win+
- 一个错误:多线程使用单一消费者下图显现了一种错误的使用KafkaConsumer的方法创建多个线程用来消费kafka数据多线程使用同一个Ka
- 对于服务器端开发人员而言,调用第三方接口获取数据,将其“代理”转化并返给客户端几乎是家常便
- 一、实现方式@ConfigurationProperties 注解(最好加上前缀prefix=“person”,标明是和配置文件中哪个开头的
- SimpleDateFormat是处理日期格式转换的类。官方API_1.8关于SimpleDateFormat继承于DateFormate截
- Java基于对象流实现银行系统的具体代码,供大家参考,具体内容如下系统特点:数据持久化到文件中,系统启动后,加载文件中数据到集合中,相当于做
- 这篇文章主要介绍了springboot如何使用AOP做访问请求日志,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价
- Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个
- 一、选择结构大纲if单选择结构if双选择结构if多选择结构嵌套的if结构switch多选择结构二、if单选择结构我们很多时候需要去判断一个东
- 1.算法效率算法效率分析分为两种:第一种是时间效率,第二种是空间效率。时间效率被称为时间复杂度,而空间效率被称作空间复杂度。时间复杂度主要衡
- 1.申请测试号,并记录appID和appsecret2.关注测试号3.添加消息模板{{topic.DATA}} 用户名: {{user.DA
- 本文实例讲述了Java Web实现添加定时任务的方法。分享给大家供大家参考,具体如下:定时任务时间控制类/** * 定时任务时间控制 * *
- 一本书的页码从自然数1开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。例如第6页用6表示而不是06或0
- 模式介绍命令模式(Command Pattern) :在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被
- 什么是JMMJMM全称Java Memory Model, 中文翻译Java内存模型,一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问