用反射实现对象与对象之间的赋值

努力了这么久,但凡有点儿天赋,也该有些成功的迹象了。

前言

  最近做的一个项目需要经常给对象赋值,或者说把一个数据库的实体对象转化成elasticsearch中的存储对象,要是属性没几个,倒是还好点,几行set方法就搞定了,要是对象的属性一多,几十个上百个属性,那完犊子了,写上几十上百行的set方法,那种代码体验着实让人想吐,比如像下面这个样子:

在这里插入图片描述
一屏幕都截取不完,看上边图片上右下角标红的那部分代码小地图,这也就五十个左右的属性,我就写了这么一次都要疯掉了,当我看到另一个对象里有158个属性的时候我就彻底崩溃了。我绝对绝对不想再体验一次了。于是我就想着能不能用反射来获取所有的属性,然后通过循环给对象赋值。说干就干,接下来我们开始进入正题。

首先引入Hutool包

  自从我知道了这个包之后我就太喜欢这个工具包了。真的是想要什么工具都有,我就是试一试看看它有没有反射工具包,没想到它还真的有。那么我们就先引入Hutool吧:

 <dependency>
     <groupId>cn.hutool</groupId>
     <artifactId>hutool-core</artifactId>
     <version>5.2.4</version>
 </dependency>

准备两个对象

  然后我们先准备两个类,用来互相转化,一个VblogUser,一个UserDTO。用反射来获取VblogUser的值并赋值给UserDTO。简单起见,我们两个类的属性一模一样。

@Data
public class VblogUser {
    private Long id;             //主键
    private String username;     //用户名
    private String password;     //密码
    private String nickname;     //昵称
    private boolean enabled;     //是否禁用
    private String email;        //邮箱
    private String userface;     //头像
    private String regTime;        //注册时间
}

---------------------------------------------------------------------------

@Data
public class UserDTO {
    private Long id;             //主键
    private String username;     //用户名
    private String password;     //密码
    private String nickname;     //昵称
    private boolean enabled;     //是否禁用
    private String email;        //邮箱
    private String userface;     //头像
    private String regTime;      //注册时间
}

模拟数据

  接下来我们写个方法给VblogUser 对象赋值。假装我们是从数据库里查询出来的数据。

 /**
  * 创建对象,模拟数据
  * @return
  */
 public static VblogUser creatUser(){
     VblogUser user = new VblogUser();
     user.setId(1024L);
     user.setNickname("朽木");
     user.setPassword("123456");
     user.setUsername("亚索");
     user.setEmail("1234566665@qq.com");
     user.setUserface("xiumu.jpg");
     user.setEnabled(true);
     user.setRegTime(DateUtil.now());
     return user;
 }

反射实现赋值的思路

  通过我的实验,使用Field直接调用set方法,或者用Hutool反射工具类里边的setFieldValue方法来进行赋值是有问题的,会报异常,然后我又没解决它,所以我就换了个方式来进行赋值。

  • 首先获取对象所有的属性并进行循环
  • 然后根据属性名字生成这个属性的set方法名
  • 再调用这个set方法进行赋值

开始写对象转化工具类

  首先我们需要创建一个工具类,写上两个通用方法。第一个方法就是根据属性名字生成set方法名。我们知道set方法名一般就是把属性首字母大写,然后加上一个set前缀。

/**
 * 根据属性名获取set方法名
 * @param fieldName 属性名
 * @return
 */
private static String getSetMethodName(String fieldName) {
    char[] field = fieldName.toCharArray();
    //首字母大写
    field[0] -= 32;
    //加上set前缀
    return "set"+String.valueOf(field);
}

第二个方法就是调用该对象的set方法给属性赋值

/**
  * 给目标对象赋值
  * @param userDTO 目标对象
  * @param fieldName 属性名
  * @param value 值
  */
 private static void setFieldValue(UserDTO userDTO, String fieldName, Object value) {
     //使用Hutool的反射工具类获取set方法
     Method method = ReflectUtil.getMethodByName(userDTO.getClass(),getSetMethodName(fieldName));
     //使用Hutool的反射工具类调用set方法给对象赋值
     ReflectUtil.invoke(userDTO,method,value);
 }

  接下来就是获取所有的属性并循环给对象赋值

/**
 * 将VblogUser转化成userDTO
 * @param user
 * @return
 */
public static UserDTO transformUser(VblogUser user){
    UserDTO userDTO = new UserDTO();
    //获取对象所有的属性
    Field[] fields = ReflectUtil.getFields(UserDTO.class);
    for (Field field : fields) {
        //根据属性名获取属性的值
        Object value = ReflectUtil.getFieldValue(user, field.getName());
        if (value != null){
            //给对象赋值
            setFieldValue(userDTO,field.getName(),value);
        }
    }
    return userDTO;
}

测试结果

  接下来我们写个main方法来测试一下这个工具好不好用。

public static void main(String[] args) {
    VblogUser vblogUser = creatUser();
    System.out.println(vblogUser);
    UserDTO userDTO = BeanTransformUtil.transformUser(vblogUser);
    System.out.println(userDTO);
}

结果截图:
在这里插入图片描述
我们可以看到,这个方法还是挺好的,只要写好了工具类,只需要用这短短几行代码就可以完成对象与对象之间的赋值。

代码放在gitee上:https://gitee.com/siumu/blog_code.git
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值