开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
前言:
如果有人问我如何提升代码的简洁度,反射一定在我的回答里面。工作了一些年,呆过几个公司,发现大家都知道反射也知道反射的一些常用api,但是应用在项目中的还是很少,下面我举例几个在业务开发中可以用到反射的地方。
一丶检验参数是否全部填写
我们在工作中经常会遇到这样的需求,前端页面的一些表单字段必须全部填写才能提交表单,这里一般前端会在页面上校验参数是否填写,但是如果只做了前端的校验,其实我们可以通过直接调用接口的方式发送请求,这个时候我们就需要在后端也校验一下参数是否全部填写,一般页面的表单会对应数据库的一个或者多个实体,下面我们以User对象举例,来看看反射校验参数是否全部填写的场景。
- 实体
@Data
public class User {
private Long id;
private String name;
private Integer age;
private Integer sex;
}
- 普通方式校验参数是否必填
private void checkUserRequired(User user) {
if (Objects.isNull(user.getAge())
|| Objects.isNull(user.getSex())
|| StringUtils.isEmpty(user.getName())) {
throw new RuntimeException("Please complete the form before submitting.");
}
}
- 使用反射校验参数是否必填
private <T> void checkUserRequiredReflect(T t) throws IllegalAccessException {
Class<?> clzss = t.getClass();
Field[] fields = clzss.getDeclaredFields();
for (Field field : fields) {
String name = field.getName();
if (Objects.equals(ID, name)) {
continue;
}
if (Objects.isNull(field.get(t))) {
throw new RuntimeException("Please complete the form before submitting.");
}
}
}
二丶填充通用字段
现在我们数据库表一般都会有几个通用字段,比如更新人,更新时间,创建人,创建时间,是否删除等。例如:我们在删除的时候都要更新更新人、更新时间、是否删除字段,我们这里就可以用反射来写一个通用的方法。
- 实体
@Data
public class User {
private Long id;
private String name;
private Integer age;
private Integer sex;
private Long updateUser;
private Date updateTime;
private Integer isDelete;
}
- 普通方式填充通用字段
private void buildUserDeleted(User user) {
user.setUpdateUser(111l);
user.setUpdateTime(new Date());
user.setIsDelete(1);
}
- 使用反射填充通用字段
private <T> void buildEntityDeletedByReflect(T t) throws IllegalAccessException {
Class<?> clzss = t.getClass();
Field[] fields = clzss.getDeclaredFields();
for (Field field : fields) {
String name = field.getName();
if (Objects.equals("updateUser", name)) {
field.set(t, 111l);
continue;
}
if (Objects.equals("updateTime", name)) {
field.set(t, new Date());
continue;
}
if (Objects.equals("isDelete", name)) {
field.set(t, 1);
}
}
}
总结
可能看到上面的例子有人说,你填充字段写了那么多代码,我设置三个属性就三行代码就行了,但是普通方式填充通用字段,我们一个实体就需要写一个那样的build方法,而我们通过反射的方式设置字段值,可以用在任何的实体对象上面(存在这三个字段的实体类)。相信大家看到这里发现反射的好处,我们可以不用显示指定对象的类型来操作一个对象,我们将之前需要编译期就确定对象类型延后到了运行期去了,这样我们就可以针对对象做一些通用的操作。