如何避免或者减少线上空指针问题的发生

一、背景

在我们的日常工作中,我们会经常遇到空指针问题,理论上来说只是一个判段空指针的小问题,但是因为这行代码的报错,程序中断了后面的执行,可能导致整体业务逻辑受影响。那在工作中我们应该如何避免,或者说降低空指针的发生。下面讲一下我的个人感悟

二、如何避免或者减少空指针问题的发生

(1)使用对象时养成不信任意识

一定要记住无论用什么方法避免空指针,最好的手段永远是不信任意识,只有不信任意识养成了,我们在写代码的时候在用一个对象的时候,自然而然就会想到这个对象是否会为空,只有这层意识养成了,你才能避免绝大多数空指针场景

在这里将我们一般常用的对象总结一下

  • 自己手动new出来的对象
  • 从数据库查询数据转换出来的查询对象(一般是一个集合)
  • 框架(一般大家都是用Spring全家桶)帮我们创建的对象
  • 通过调用外部接口返回的数据形成的数据对象
  • .........

在我们使用对象的时候都要有不信任的意识,他是否为空对象,对象里面的对象是否为空对象。这样才能大概率避免空指针场景

(2)使用JDK1.8特性 Optional工具封装方法

Optional有两个用法

  • 封装方法返回值

我们来看这样一段方法

假设会员积分超过1000,则返回一台电脑,然后用电脑玩

/**
     * @author chen
     * @description 如果会员积分大于1000则奖励一台电脑
     * @param memberPointsNumber 会员积分
     * @date: 2024/8/6 11:06
     * @return bio.Computer
     */
    public Computer getComputer(int memberPointsNumber){
        if(memberPointsNumber < 1000){
            return null;
        }
        return new Computer();
    }

假设我们使用的时候是这样,直接调用,则就可能会出现空指针的现象,所以这个非常取决于调用者的意识,调用者意识好,会进行空指针判断,则可以避免

   Computer computer = testDemo.getComputer(800);
   //拿到这个对象直接判空则会引发空指针
   computer.doPlayGame();
Exception in thread "main" java.lang.NullPointerException
	at CopyArrayListDemo.main(CopyArrayListDemo.java:21)

我们可以使用Optional进行改进一下

/**
     * @author chen
     * @description 如果会员积分大于1000则奖励一台电脑
     * @param memberPointsNumber 会员积分
     * @date: 2024/8/6 11:06
     * @return bio.Computer
     */
    public Optional<Computer> getComputer(int memberPointsNumber){
        if(memberPointsNumber < 1000){
            return Optional.empty();
        }
        return Optional.of(new Computer());
    }

如果调用者不进行空判断,则IDEA会自己进行深颜色告警

所以我们正确的写法是,利用Optional的特性对使用对象进行检查,借助Optional特性让调用方强制检查,从而减少空指针的发生

    Optional<Computer> computerOptional = testDemo.getComputer(800);
    //使用Optional的特性进行判空
    if(!computerOptional.isPresent()) {
        return;
    }
    Computer computer = computerOptional.get();
    computer.doPlayGame();
  • 嵌套对象获取

在没使用Optional时,我们获取嵌套对象如果需要判空则需要这样做

举一个获取Computer类的USB类的版本号为例,需要获取对象判断空指针,如果对象嵌套层级深要判断多次空指针

        Computer computer = computerOptional.get();
        //获取USB对象
        USB usb = computer.getUsb();
        Integer version = 1;
        if(Objects.nonNull(usb)){
            version = usb.getVersion();
        }
        System.out.println("USB 版本号是 : " + version);

我们也可以使用Optional来这样写,代码更加简洁,以及工具会帮我们进行空指针判断

        Computer computer = computerOptional.get();
        //使用Optional来进行获取版本号,简化代码的同时以及能做到空指针判断
        Integer version = Optional.of(computer).map(Computer::getUsb).map(USB::getVersion).orElse(1);
        System.out.println("USB 版本号是 : " + version);

(3)使用Hutool转换类进行转换

在我们的工作中,数据转换是我们常常会遇见的,例如String转Integer,Integer转Double等等,Hutool工具包里面帮我们提供了工具类转换,即使转换失败也不会报错,可以大大提高代码的健壮性,举String转Integer为例

我们一般这样写,代码存在风险,Integer.parseInt方法不会判空,如果字符串不是数字也会报错

        String a = "123";
        //Integer.parseInt方法不会判空,如果字符串不是数字也会报错
        Integer result = Integer.parseInt(a);

假设我们使用hutool工具包提供的类,代码很稳定,即使变量a是非数字也不会报错,转换的api也很丰富,也支持转换失败返回默认值,具体可以去hutool工具官网上了解

类型转换工具类-Convert | Hutool

        String a = "123";
        Integer result = Convert.toInt(a);

(4)代码扫描工具

代码扫描工具很多公司都是自己搭建的,这个不详细说了,比较火的有FindBugs、PMD、SonarQube、Fortify、WebInspect,对于一些常规的空指针错误是能够帮你扫描出来的,也算是减少或者避免空指针问题的工具

三、总结

任何工具都是辅助,就像我之前说的,只有不信任意识才是最终的道路,可以结合工具,然后逐步养成不信任意识,在写代码的道路上越来越严谨,出问题的概率当然就越来越小。祝愿大家写的代码越来越越稳如泰山。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值