Java循环对bean的属性进行赋值的实现
作者:BHBshy 发布时间:2023-01-27 10:18:05
标签:Java,bean,属性,赋值
项目背景
我们开发过程中会碰到这样一类问题,就是数据层或三方接口返回的Bean对象需要转换重新装换一下我们需要的对象。我们通常的做法就是通过getter/setter方法进行一个一个进行赋值,这样的话书写起来太复杂了,并且太重复了。我尝试写了一个工具类,能够对各种场景下的对象进行相互赋值。
功能介绍
可以为将要赋值的对象进行单个单个的按顺序赋值
通过传递的属性的index(就是他是第几个属性)获取本属性的值
返回对象中属性的数量
两个对象之间相互拷贝属性值
传递一个list,遍历bean进行赋值
传递一个数组,对对象进行赋值
返回一个对象的属性值集合
返回一个对象的属性值数组
注意注意注意!!!
getDeclaredFields方法不能保证字段声明的顺序进行返回,但是基本上会按照这个顺序的。所以以下的方法是建立在返回正确的顺序上的基础上的,但是两个对象相互拷贝是没有问题的。
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* @author haoyan.shi
* 想设计一个能够解析一个bean的全部属性并按照顺序进行遍历
*/
public class ObjectUtils {
/**
* 按照属性的顺序赋值。可接受null,但是不能跳过某个属性进行赋值。就是说就算
* 有一个值为空,那你也要传递进行null
*
* @param target
* @param value
* @param <E>
* @return
*/
public static <E> E forEachSetValue(E target, Object value) {
if (target == null) {
return target;
}
List<Field> fields = new ArrayList<>();
try {
// 1.解析出所有的属性
Field[] declaredFields = target.getClass().getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
fields.add(declaredField);
}
// 2.把每个属性放入一个集合中
if (fields.size() <= 0) {
return target;
}
while (fields.get(0).get(target) != null) {
fields.remove(0);
}
Field field = fields.get(0);
field.set(target, value);
fields.remove(0);
} catch (Exception exception) {
exception.printStackTrace();
}
return target;
}
/**
* 本方法为了遍历索引进行赋值
*
* @param e
* @param index
* @return
*/
public static Object forEachGetValue(Object e, int index) {
try {
Field[] declaredFields = e.getClass().getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
}
return declaredFields[index].get(e);
} catch (IllegalAccessException illegalAccessException) {
illegalAccessException.printStackTrace();
}
return e;
}
public static int size(Object o) {
if (o == null) {
return 0;
}
Field[] declaredFields = o.getClass().getDeclaredFields();
return declaredFields.length;
}
/**
* 本方法是为了把已经有值得对象中属性名相同的名属性赋值到没有值得对象用。
*
* @param target
* @param value
*/
public static <E> E copyValueFromObject(E target, Object value) {
if (target == null || value == null) {
return null;
}
Field[] vs = target.getClass().getDeclaredFields();
Field[] ts = value.getClass().getDeclaredFields();
try {
for (int i = 0; i < vs.length; i++) {
for (int j = 0; j < ts.length; j++) {
if (vs[i].getName().equals(ts[j])) {
ts[j].set(target, vs[i].get(value));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return target;
}
/**
* 这个方法能把list中的值按照顺序设置到目标对象中
*
* @param target
* @param value
* @param <E>
* @return
*/
public static <E> E forEachSetValueFromList(E target, List value) {
if (target == null || value == null || value.size() == 0) {
return target;
}
Field[] ts = target.getClass().getDeclaredFields();
try {
for (int i = 0; i < ts.length; i++) {
ts[i].set(target, value.get(i));
}
} catch (Exception e) {
e.printStackTrace();
}
return target;
}
/**
* 从数组中进行设置值
*
* @param target
* @param value
* @param <E>
* @return
*/
public static <E> E forEachSetValueFromArray(E target, Object[] value) {
if (target == null || value == null || value.length == 0) {
return target;
}
Field[] ts = target.getClass().getDeclaredFields();
try {
for (int i = 0; i < ts.length; i++) {
ts[i].set(target, value[i]);
}
} catch (Exception e) {
e.printStackTrace();
}
return target;
}
public static Object[] getArrayValue(Object o) {
Field[] declaredFields = o.getClass().getDeclaredFields();
Object[] result = new Object[declaredFields.length];
try {
for (int i = 0; i < declaredFields.length; i++) {
result[i] = declaredFields[i].get(o);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static List getListValue(Object o) {
Field[] declaredFields = o.getClass().getDeclaredFields();
List result = new ArrayList(declaredFields.length);
try {
for (int i = 0; i < declaredFields.length; i++) {
result.add(declaredFields[i].get(o));
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
后期扩展:
1.我们可以定义一些注解,进行属性匹配。注入值更精确。
2.还可以用jdk1.8中的函数接口,进行赋值。
3.甚至都可以作为jdk的新特性去扩展这个功能。
来源:https://blog.csdn.net/qq_40395687/article/details/108200619


猜你喜欢
- 这篇文章主要介绍了RabbitMQ延迟队列及消息延迟推送实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- C#申请一个大数组(Use a large array in C#)在C#里,有时候我需要能够申请一个很大的数组、使用之、然后立即释放其占用
- 目录一、SpringBoot 使用 Nacos Config 实现多环境切换1. 现象2. 引入依赖3. 添加bootstrap.yaml配
- 首先写布局文件activity_main.xml:<LinearLayout xmlns:android="http://s
- #define只加一个参数 的解释<stdio.h> 里有:#ifndef __STDIO_H #define &n
- 前段时间摸索了java调用matlab东西,不说学的有多深,也算有结果了,达到目的了。也即用java程序可以调用matlab中函数了。&nb
- 1.Object类是什么?🟪Object 是 Java 类库中的一个特殊类,也是所有类的父类。也就是说,Java 允许把任何类型的
- 一、 PorterDuffXfermodePorterDuffXfermode类似于数据集合里面的交集并集概念,只是数据里面取的是两个集合,
- 前言:学习二叉树的基本操作前,需要先创建一颗二叉树,然后才能学习其相关的基本操作,考虑到我们刚刚接触二叉树,为了能够先易后难地进行讲解,我们
- 全面解析java注解Java中的常见注解 a.JDK中的注解 @Override 覆盖父类或者父接口的方
- Prim算法介绍1.点睛在生成树的过程中,把已经在生成树中的节点看作一个集合,把剩下的节点看作另外一个集合,从连接两个集合的边中选择一条权值
- 查看apiDemos,找到View/Animation/shake找到对应的动画代码,直接拷贝过来当导入一个项目的时候,报R文件不存在,很多
- 前言有时候我们在项目中,会用到一些本地 jar 包文件,比如隔壁公司自己打包的;此时无法从maven远程仓库拉取;那么我们可以考虑把 jar
- public class TestSqlserverJtds { public static void main(String[]
- 前面介绍了Spring Boot 整合mybatis 使用注解的方式实现数据库操作,介绍了如何自动生成注解版的mapper 和pojo类。
- 1、cmd指令,进入.svn目录,找到wc.db文件 sqlite 3 打开2、 对 svn源代码目录 右键, clean up, 稍等1至
- Android原生控件只有横向进度条一种,而且没法变换样式,比如原生rom的样子很丑是吧,当伟大的产品设计要求更换前背景,甚至纵向,甚至圆弧
- System.getProperty(user.dir)定位问题前言随着学习java web 的深入学习,为了巩固自己的学习成果,练习了一个
- 最近经常有人问Spring Cloud Feign如何上传文件。有团队的新成员,也有其他公司的兄弟。本文简单做个总结——早期的Spring
- 简单工厂简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。定义了一个创建对象的类,由