java反射机制给实体类相同字段自动赋值实例
作者:The best are water 时间:2023-11-25 19:52:29
一、封装一个工具类
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
标签:java,反射,实体类,字段,赋值
0
投稿
猜你喜欢
C#创建windows系统用户的方法
2022-07-16 20:30:12
Android 滑动返回Activity的实现代码
2023-12-09 22:56:58
Unity实现打砖块游戏
2023-12-06 04:45:04
详解Android App中创建ViewPager组件的方法
2023-07-12 00:46:14
WPF自定义控件的实现
2021-07-06 02:34:11
C#生成PDF文件流
2023-03-19 08:52:56
Android 高仿微信语音聊天页面高斯模糊(毛玻璃效果)
2021-09-27 18:56:46
C#操作EXCEL DataTable转换的实例代码
2022-05-18 04:25:15
Java实现合并多个PDF的示例代码
2023-04-29 13:25:32
eclipse配置tomcat10的详细步骤总结
2021-10-04 03:34:25
C#中登录窗体和欢迎窗体关闭方法分析
2023-03-23 03:58:25
java之swing表格实现方法
2023-06-05 09:44:03
官网项目Jetpack Startup库学习
2021-10-03 16:33:21
Spring Cloud Gateway 远程代码执行漏洞(CVE-2022-22947)的过程解析
2021-10-03 11:25:56
Java MultipartFile实现上传文件/上传图片
2022-04-19 07:07:19
Maven中的SnapShot版本和正式版本的区别
2023-11-03 16:31:46
Android四大组件之Service详解
2023-10-16 14:22:38
c# 根据NPOI 读取一个excel 文件的多个Sheet
2021-11-30 05:10:55
C#进制之间的相互转换详解
2022-07-24 11:47:53
Android ViewPager实现轮播图效果
2023-03-09 20:44:53