利用「注解」和「反射」将BigDecimal属性中的NULL转换为0

createh51周前 (03-06)技术教程2

Java中的反射在Spring这些框架中应用的很频繁,比如Spring容器初始化Bean的过程等等,但是在实际的业务开发中自己却应用的很少。

最近的开发过程中正好有个这样的需求,有几个实体类中属性比较多,而且这些属性都是定义的返回金额字段,因为金额在计算过程中可能出现精度问题,所以定义金额字段属性都使用的BigDecimal进行修饰。在和前端对接的过程中发现有些金额字断返回的NULL,这样就产生了一些歧义,因为NULL和0并不是一码事,需要后端给出清晰返回,这个问题处理起来并不复杂,下面整理了几种处理方案:

  1. 修改查询sql,查询时NULL的属性使用IFNULL函数转为0;
  2. 在属性的setXxx方法时统一判断一下如果set值为NULL则转换为返回BigDecimal.ZERO;
  3. 在属性上增加注解,返回实体信息时统一使用反射进行属性转换;

因为返回实体属性较多,第3种方案明显要优于第2种,这样不用大面积做属性转换,代码也更加简洁。相对于第3种方案来说,第1种需要重写sql,改动则较多。

下面是具体实现方法:

定义注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface IsNullConvertZero {
  
}

定义校验实体Util类

@Slf4j
public class IsNullConvertZeroUtil {

    public static Object checkIsNull(Object obj) {
        try {
            Class clazz = obj.getClass();
            //获得私有的成员属性
            Field[] fields = clazz.getDeclaredFields();
            if(Objects.nonNull(fields) && fields.length>0){
                for(Field field : fields){
                    field.setAccessible(true);
                    //判断IsNullConvertZero注解是否存在
                    if(field.isAnnotationPresent(IsNullConvertZero.class)){
                        if(Objects.isNull(field.get(obj))){
                            field.set(obj, BigDecimal.ZERO);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("IsNullConvertZeroUtil出现异常:{}",e);
        }
        return obj;
    }
}

定义返回实体类

@Data
@ToString
public class ServcenterAccountDTO {
    @IsNullConvertZero
    private BigDecimal businessPaymentBeginBalance;
    @IsNullConvertZero
    private BigDecimal businessReceiptTodayAmount;
    @IsNullConvertZero
    private BigDecimal businessRefundTodayAmount;
    @IsNullConvertZero
    private BigDecimal tempReserveBeginBalance;
 	  /**
     * 还有很多属性,就不罗列了
     */
}

使用示例

ServcenterAccountDTO servcenterAccountDTO = new ServcenterAccountDTO();
servcenterAccountDTO.setBusinessPaymentBeginBalance(businessPaymentBeginBalance);
servcenterAccountDTO.setBusinessReceiptTodayAmount(businessReceiptTodayAmount);
servcenterAccountDTO.setBusinessRefundTodayAmount(businessRefundTodayAmount);
servcenterAccountDTO.setTempReserveBeginBalance(tempReserveBeginBalance);
/**
  * 还有很多属性,就不罗列了
 */
//通过反射校验注解将属性值NULL转为BigDecimal.ZERO
IsNullConvertZeroUtil.checkIsNull(servcenterAccountDTO);

return servcenterAccountDTO;

不断分享开发过程用到的技术和面试经常被问到的问题,如果您也对IT技术比较感兴趣可以「关注」我

相关文章

Java 判断对象是否所有属性为空,大家觉得这样写可以吗?

序言:在开发Excel数据导入的时候,后台拿到Excel中的数据并接收到List泛型集合中,发现有很多对象的属性全部为null,想通过代码将这些无效的数据给过滤掉,下面是过滤的具体操作。ObjectU...

java8之Optional 判空,简化判空操作

导语在没有用Optional判空之前,你是否也像下面的代码一样判空呢?如果是,请往下看,Optional 相对传统判空的优势。传统阶层判空为什么要用Optional,它到底是什么东西你也看到了上面的那...

Java中的空指针怎么处理?

#暑期创作大赛#Java程序员工作中遇到最多的错误就是空指针异常,无论你多么细心,一不留神就从代码的某个地方冒出NullPointerException,令人头疼。1. 对象设置默认值Object o...

java catch 空指针异常_关于Java:捕获空指针异常

我想问的是有关Java的多数知识,但我想它适用于许多语言。考虑,if(myVariable==null){doSomethingAboutIt();}else carryOn(myVariable);...

java 中如何避免空指针

在Java中,空指针异常(NullPointerException)是常见的运行时异常,通常是因为在对一个空对象(null)进行方法调用、字段访问等操作时引起的。为了避免空指针异常,可以采取以下几种方...

告别空指针-Kotlin这一点把Java比下去了

写Java的各位想必没少被空指针异常(NullpointException)困扰,但在Kotlin中,我们终于可以跟它Say Goodbye了。严格来说,Kotlin中不是消灭了空指针异常,而是通过更...