乐趣区

关于java:记一次判断值是否存在遇到的神奇问题

前言

最近敌人说遇到一个无解的 bug,他有个业务需要是 VIP 用户能力参加流动的业务场景。他判断 vip 的伪代码形如下

private boolean isVip(UserDTO userDTO){List<Integer> vipUserIds = userService.vipUserIds();
        for (Integer vipUserId : vipUserIds) {if(vipUserId.equals(userDTO.getUserId())){return true;}
        }


        return false;
    }

他传了一个 userId 为 10000(注:10000 为示例数据)的 vip 用户,后果发现这个判断始终是 false。于是就找到我帮他看下,这代码看着没啥问题,我就让他先确认一下数据库是否存在这个 vip 用户,敌人十分必定的说存在的。

排查

因为敌人确定数据库存在这条记录,前面我就让他判断 vip 的逻辑上加下日志,改后的伪代码如下

private boolean isVip(UserDTO userDTO){List<Integer> vipUserIds = userService.vipUserIds();
        for (Integer vipUserId : vipUserIds) {if(vipUserId.equals(userDTO.getUserId())){return true;}
        }

        log.warn("userId-->{} is not in vipList-->{}",userDTO.getUserId(),vipUserIds);

        return false;
    }

而后日志神奇的呈现

当看到这条日志,我就有点懵逼了。前面敌人跟我说他狐疑是 JDK 版本有问题,但我的第六感通知这不至于。

多年写 bug 教训通知我,啥都会骗人,只有源码不会骗人。因为判断是否 vip 的代码就一句 equal,间接点进去了事。这 equal 的源码如下

   public boolean equals(Object obj) {if (obj instanceof Integer) {return value == ((Integer)obj).intValue();}
        return false;
    }

看到这个代码后,我想有些老司机应该有点感觉。前面我就跟敌人说你有没有可能类型写错了,你的 userId 类型是 Integer 吗?于是他翻一下代码,果然他 userId 的类型写成 String

修复

前面敌人把 userId 的类型也改成 Integer,问题圆满解决。

总结

有时候有些 bug 难以解决,并不是因为遇到技术难题,而是因为一些咱们平时没留神的小细节引起

退出移动版