首页 > 编程语言 >Java对象中转换空值的字段

Java对象中转换空值的字段

时间:2023-06-09 18:12:45浏览次数:34  
标签:info ConvertNullFiledInfo 转换 空值 field result Java null class

在后端返回数据给前端时,公司的框架会把值为null的数据去掉,方便前端取值。

如: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;
    }
    
}

运行结果

可以看到是正常转换了的

问题点

这样写虽然简单方便,但是如果有非常多的对象需要转换,就会有许多重复代码;

而且如果字段有修改(类型、名称、被删除、新增),就需要在去转换方法中修改,因此可以用更好的方式。

 

遍历Filed转换

所有对象都有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);
}

运行结果

成功转换

 

标签:info,ConvertNullFiledInfo,转换,空值,field,result,Java,null,class
From: https://www.cnblogs.com/kzyuan/p/17469931.html

相关文章

  • 大家都说Java有三种创建线程的方式!并发编程中的惊天骗局!
    在Java中,创建线程是一项非常重要的任务。线程是一种轻量级的子进程,可以并行执行,使得程序的执行效率得到提高。Java提供了多种方式来创建线程,但许多人都认为Java有三种创建线程的方式,它们分别是继承Thread类、实现Runnable接口和使用线程池。但是,你们知道吗?其实在创建线程的过程中......
  • JavaScript 构造器模式:创建可重用的对象
    前言JavaScript是一种基于对象的语言,对象是JavaScript中最重要的概念之一。在JavaScript中,我们可以使用构造器模式来创建可重用的对象。本文将介绍JavaScript构造器模式的概念、用法和实例,并给出博客标题《JavaScript构造器模式:创建可重用的对象》。构造器模式构造器模......
  • Caused by: java.lang.ClassNotFoundException: com.alibaba.fastjson2.util.Wrap
    1.情景展示使用fastjson2,运行时报错:Causedby:java.lang.ClassNotFoundException:com.alibaba.fastjson2.util.Wrap2.具体分析出现这个问题,是因为pom.xml当中引用的有关fastjson的jar包冲突造成的。只要我们把冲突的jar包排除掉就可以了。3.解决方案在idea当中,使用插件......
  • Java 集合框架体系简介
    为什么要使用集合存储多个数据可以使用数组,但由于数组在内存中是连续存储的,所以会有一些限制。比如数组在创建时就要指定长度,即可以容纳的元素个数,且指定后无法更改;数组在创建时需要指定元素的类型,并且所有元素都必须是该类型或其子类;添加或删除数组中的元素需要创建一个新数组再......
  • go 时间戳和时间格式的相互转换
    1.日期->时间戳timestamp:=time.now().Unix()//转化为时间戳类型是int642.时间戳->日期timeNow:=time.Unix(time.Now().Unix(),0)3.日期->字符串timeLayout:="2006-01-0215:04:05"//转化所需模板timeString:=time.now().Format(layout)4.字符串->日期t......
  • java的接口和抽象类简单理解
    接口是定义了系统各模块应该遵守的标准。实现者对外提供哪些服务,调用者可以调用哪些服务以及如何调用服务。抽象类作为系统中各个子类的共同父类,所表现的是一种模板设计,只实现了最基础的共通功能,相当于一个中间产品,各个子类具体实现抽象方法。抽象类可以没有抽象方法,......
  • java8如何校验ssh-keygen生成的公私钥
    如果你的公私钥文件不是PEM格式的,而是其他格式,如OpenSSH格式(通常以`id_rsa`和`id_rsa.pub`命名),你可以使用Java的`JSch`库来验证它们的有效性。下面是一个示例代码,演示如何使用`JSch`库验证OpenSSH格式的公私钥对:首先,你需要在项目中引入JSch库的依赖。你可以使用Maven或手动下载并......
  • java不打印异常堆栈
    背景:生产环境抛异常,但却没有将堆栈信息输出到日志,只有简单的java.lang.NullPointerException错误信息。原因分析JVM在默认启动的时候会加上OmitStackTraceInFastThrow参数,含义是当大量抛出同样的异常的后,后面的异常输出将不打印堆栈。原因是打印堆栈的时候底层会调用到Throw......
  • 使用JAVA开发微信公众平台(一)——环境搭建与开发接入
    一、初始微信公众平台微信公众平台,即我们平时所说的“公众号”,曾用名“官方平台”、“媒体平台”,但最终命名为“公众平台”。从微信的命名我可以发现,公众平台不只是官方、媒体使用的平台,而是对所有公众都开放的统一平台。喜欢本文,请点击下方喜欢按钮呗!❤️微信公众平台地址:http......
  • Java面试题精华集-Java 工程师进阶知识完全扫盲
    在GitHub/Gitee编辑消息队列面试场景面试官:你好。候选人:你好。(面试官在你的简历上面看到了,呦,有个亮点,你在项目里用过MQ,比如说你用过ActiveMQ)面试官:你在系统里用过消息队列吗?(面试官在随和的语气中展开了面试)候选人:用过的(此时感觉没啥)面试官:那你说一下你们在项目里是......