🙁记录一次Long类型引发的bug

136 阅读2分钟

今天在做商品分类查询时,发现有一部分数据是可以正常把一二三级分类都查出来,而部分数据第三级的分类为空😨,检查了数据库发现数据并无问题。发生问题时,截图如下:

😮部分无三级分类

image.png

🤡查询数据的部分业务代码如下:

private List<Category> getAllCategoryForTree(Long pid, List<Category> all) {
    List<Category> categoryList = new ArrayList<>();
    all.stream().forEach(category -> {
        //注意这里
        if(category.getParentCid() == pid){
            if(hasChildren(category,all)){
                List<Category> children = getAllCategoryForTree(category.getCatId(), all);
                category.setChildren(children);
            }
            categoryList.add(category);
        }
    });
    return categoryList;
}

💗问题其实出在category.getParentCid()与pid的值都是Long类型,而Long类型的部分源码如下:

@IntrinsicCandidate
public static Long valueOf(long l) {
    final int offset = 128;
    if (l >= -128 && l <= 127) { // will cache
        return LongCache.cache[(int)l + offset];
    }
    return new Long(l);
}
private static class LongCache {
    private LongCache() {}

    static final Long[] cache;
    static Long[] archivedCache;

    static {
        int size = -(-128) + 127 + 1;

        // Load and use the archived cache if it exists
        CDS.initializeFromArchive(LongCache.class);
        if (archivedCache == null || archivedCache.length != size) {
            Long[] c = new Long[size];
            long value = -128;
            for(int i = 0; i < size; i++) {
                c[i] = new Long(value++);
            }
            archivedCache = c;
        }
        cache = archivedCache;
    }
}

💦查阅资料可知,对于Long类型,如果传入的基本类型在-128-127之内就,就从LongCache中取数据返回给我们,数据库中,分类id的值大部分都超过了127,在我的代码中,需要多次对Long类型的数据进行相等判断,一旦数据超过127,就会new Long(),此时再用 == 进行比较得到的结果就一定为false了。

在单元测试中证明😃

@Test
void testLong(){
   Long a = 100L;
   Long b = 100L;
   
   //value超过127
   Long c = 128L;
   Long d = 128L;

   System.out.println(a == b);
   System.out.println(c == d);
}

结果:

image.png

⭐⭐⭐因此修改我的业务代码:使用longValue()方法

all.stream().forEach(category -> {
    if(category.getParentCid().longValue() == pid.longValue())
    ...
    ...

longValue()方法源码:

image.png

⭐⭐⭐或者对于Long类型来说,直接使用equals进行比较是否相等也是可以的。

参考文章:segmentfault.com/a/119000002…