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


猜你喜欢
- 前言基本语法首先我们要知道java的基础语法。1.由26个英文字母大小写,0-9,_或$组成2.数字不可以开头3.不可以使用关键字和保留字,
- 本文实例为大家分享了Android绝对布局AbsoluteLayout的具体代码,供大家参考,具体内容如下1>AbsoluteLayo
- 线程(Thread)是并发编程的基础,也是程序执行的最小单元,它依托进程而存在。一个进程中可以包含多个线程,多线程可以共享一块内存空间和一组
- 一、项目介绍【知识准备】①Android Interface definition language(aidl,android接口定义语言)
- Java 散列存储Java中散列存储的数据结构主要是指HashSet、HashMap、LinkedHashSet、LinkedHashMap
- 基于有了OO的基础后,开始认真学习设计模式!设计模式是java设计中必不可少的!Apple.javapackage strategy;/**
- 一、引言Good Good Study,Day Day Up,童鞋点个关注,不迷路,么么哒~~~MP自带的条件构造器虽然很强大,有时候也避免
- 现在很多android的应用都采用底部导航栏的功能,这样可以使得用户在使用过程中随意切换不同的页面,现在我采用TabHost组件来自定义一个
- 前面文章介绍了Android利用麦克风采集并显示模拟信号的实现方法,这种采集手段适用于无IO控制、单纯读取信号的情况。如果传感器本身需要包含
- 1.SpringCache的概念首先我们知道jpa,jdbc这些东西都是一些规范,比如jdbc,要要连接到数据库,都是需要用到数据库连接,预
- 本文实例为大家分享了Java Socket实现多人聊天系统的具体代码,供大家参考,具体内容如下前言GitHub地址开发环境:Eclipse
- 注解定义: 注解是一种注释机制,它可以注释包、类、方法、变量、参数,在编译器生成类文件时,标注可以被嵌入到字节码中。注解的分类:内置注解Ov
- 前言TensorFlow是Google开源的一款人工智能学习系统。为什么叫这个名字呢?Tensor的意思是张量,代表N维数组;Flow的意思
- JSONObject的使用 一、 JSON对象的使用:String content = "{'username&
- 使用场景EntityListeners在jpa中使用,如果你是mybatis是不可以用的它的意义对实体属性变化的跟踪,它提供了保存前,保存后
- 笔者在网上发现了,很多种方法 ,当然咱们找最好用的,也简单的 下面废话不多说直接上代码 我在啰嗦几句 第一这个脚本挂在需要相应的游戏体上 第
- Android实现TextView超链接一共有五种方式:推荐第四种、第五种1. 直接在xml文件中配置autoLink属性(简单易用,效果单
- 图片解析:1.生成字节码文件的过程可能产生编译时异常(checked),由字节码文件到在内存中加载、运行类此过程可能产生运行时异常(unch
- 一、单线程改造为多线程也是个技术活正如我们看到耗子叔叔博客里写的那样,原来是单线程的应用程序,”后来,我们的程序性能有问题,所以需要变成多线
- 前言如今多线程编程已成为了现代软件开发中的重要部分,而并发编程中的线程同步问题更是一道难以逾越的坎。在Java语言中,synchronize