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
投稿
猜你喜欢
@valid 无法触发BindingResult的解决
2023-08-10 09:16:12
Java并发编程面试之线程池
2023-11-11 10:58:33
Java四种权限修饰符知识点详解
2023-11-11 06:12:59
ShardingSphere jdbc实现分库分表核心概念详解
2023-11-24 12:09:45
Java实现去除文档阴影的示例代码
2023-08-31 11:45:48
浅谈Java中Map和Set之间的关系(及Map.Entry)
2023-08-25 02:23:48
mybatis-generator自动生成dao、mapping、bean配置操作
2023-08-17 14:05:30
基于Java语言MD5加密Base64转换方法
2023-11-24 00:22:41
解决Spring Cloud feign GET请求无法用实体传参的问题
2023-11-17 14:14:05
Eclipse+Java+Swing+Mysql实现工资管理系统
2023-07-26 08:51:05
可视化Swing中JTable控件绑定SQL数据源的两种方法深入解析
2023-11-28 19:13:58
java中动态 代理的实现
2023-11-17 16:16:25
深入探讨Linux静态库与动态库的详解(一看就懂)
2023-07-04 01:02:28
Java中的回调
2023-11-16 01:55:58
SSH框架网上商城项目第2战之基本增删查改、Service和Action的抽取
2023-06-21 19:16:23
Flutter Widgets粘合剂CustomScrollView NestedScrollView滚动控件
2023-07-06 01:24:29
Java数据结构之单链表详解
2023-11-04 17:02:20
Springboot轻量级的监控组件SpringbootAdmin
2023-08-25 10:08:31
Java的动态分派和静态分派的实现
2023-10-09 12:58:37
sms4j 2.0 全新来袭功能的调整及maven变化详解
2023-11-05 00:31:51