Java对象中转换空值的字段
如:Person对象为:{name:"浩二", age:24, weight:null, height:114},那返回给前端的就为{name:"浩二", age:24, height:114}。
如果这个时候有个需求:
Integer类型的字段为null给-1
Long类型的字段为null给-1L
String类型的字段为null给""(空字符串)
对象类型的字段为null给new对象,
不能直接动框架,因此需要手动转化。
代码写死转换
示例
转换对象 ConvertNullFiledInfo:
@Data public class ConvertNullFiledInfo { private Integer intNum; private Long longNum; private String str; private ConvertNullFiledInfo info; }
转换代码:
@Service public class ConvertNullFiledService { /** * 写死代码的方式一个一个字段来转换 * @param info * @return */ public ConvertNullFiledInfo convertFunction01(ConvertNullFiledInfo info) { info.setIntNum(info.getIntNum() == null ? -1 : info.getIntNum()); info.setLongNum(info.getLongNum() == null ? -1L : info.getLongNum()); info.setStr(info.getStr() == null ? "" : info.getStr()); info.setInfo(info.getInfo() == null ? new ConvertNullFiledInfo() : info.getInfo()); return info; } }
测试代码:
import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @SpringBootTest @RunWith(SpringRunner.class) public class ConvertNullFiledServiceTest { @Autowired private ConvertNullFiledService convertNullFiledService; @Test public void convertFunction01() { // str和info字段给null ConvertNullFiledInfo info = createConvertNullFiledInfo(1, 1L, null, null); ConvertNullFiledInfo result = convertNullFiledService.convertFunction01(info); System.out.println(result); } /** * 自定义字段创建ConvertNullFiledInfo * @param intNum * @param longNum * @param str * @param info * @return */ private ConvertNullFiledInfo createConvertNullFiledInfo(Integer intNum, Long longNum, String str, ConvertNullFiledInfo info) { ConvertNullFiledInfo result = new ConvertNullFiledInfo(); result.setIntNum(intNum); result.setLongNum(longNum); result.setStr(str); result.setInfo(info); return result; } }
运行结果:
可以看到是正常转换了的
问题点
这样写虽然简单方便,但是如果有非常多的对象需要转换,就会有许多重复代码;
而且如果字段有修改(类型、名称、被删除、新增),就需要在去转换方法中修改,因此可以用更好的方式。
所有对象都有Class<T>类,而Class有getDeclaredFields()方法,能获取到所有字段(filed),
因此可以使用这种方式来转换。
示例
转换代码:
/** * 遍历field的方式一个一个字段来转换 * @param info * @return */ public ConvertNullFiledInfo convertByField(ConvertNullFiledInfo info) { try { Field[] fields = info.getClass().getDeclaredFields(); for (Field field : fields) { // 设置可访问私有变量 field.setAccessible(true); // 获取当前字段值 Object value = field.get(info); // value不为空就跳过 if (value != null) { continue; } // 获取当前字段类型 Class<?> type = field.getType(); if (type == Integer.class) { // Integer类型就设置为-1 field.set(info, -1); } else if (type == Long.class) { // Long类型就设置为-1L field.set(info, -1L); } else if (type == String.class) { // String类型就设置为“” field.set(info, ""); } else if (type == ConvertNullFiledInfo.class) { // ConvertNullFiledInfo类型就设置为新对象 field.set(info, new ConvertNullFiledInfo()); } } } catch (Exception e) { e.printStackTrace(); } return info; }
测试代码:
@Test public void convertByField() { // str和info字段给null ConvertNullFiledInfo info = createConvertNullFiledInfo(1, 1L, null, null); ConvertNullFiledInfo result = convertNullFiledService.convertByField(info); System.out.println(result); }
运行结果:
可以看到也是成功转换了
问题点
这种写法仍然存在问题,可以看到方法的传参和返回值都是固定类型为ConvertNullFiledInfo,
并且在遍历field的时候,也有if判断是写定的ConvertNullFiledInfo,
因此也在一定程度上写死了代码
优化
为了避免写死的情况,可以使用泛型来写
转换代码:
@Service public class ConvertNullFiledService<T> { /** * 使用泛型,遍历field的方式一个一个字段来转换 * @param object * @return */ public T convertByFieldGeneric(T object) { try { Field[] fields = object.getClass().getDeclaredFields(); for (Field field : fields) { // 设置可访问私有变量 field.setAccessible(true); // 获取当前字段值 Object value = field.get(object); // value不为空就跳过 if (value != null) { continue; } // 获取当前字段类型 Class<?> type = field.getType(); if (type == Integer.class) { // Integer类型就设置为-1 field.set(object, -1); } else if (type == Long.class) { // Long类型就设置为-1L field.set(object, -1L); } else if (type == String.class) { // String类型就设置为“” field.set(object, ""); } else if (type == object.getClass()) { // T类型就设置为新对象 Object newObj = object.getClass().newInstance(); field.set(object, newObj); } } } catch (Exception e) { e.printStackTrace(); } return object; } }
测试代码:
@Test public void convertByFieldGeneric() { // 全部字段给null ConvertNullFiledInfo info = createConvertNullFiledInfo(null, null, null, null); ConvertNullFiledInfo result = (ConvertNullFiledInfo) convertNullFiledService.convertByFieldGeneric(info); System.out.println(result); }
运行结果:
成功转换