阅读 238

一次“引用传递”引发的bug

    public static void compareJSONArray(JSONArray beforeArr,JSONArray afterArr,List<Long> addIds,List<Long> delIds){
        if (CollectionUtils.isEmpty(beforeArr) && CollectionUtils.isEmpty(afterArr)) {
            return;
        }
        if (CollectionUtils.isEmpty(beforeArr) && CollectionUtils.isNotEmpty(afterArr)) {
            // 新增
            addIds = afterArr.stream().map(id -> Long.valueOf(id.toString())).collect(Collectors.toList());
        } else if (CollectionUtils.isNotEmpty(beforeArr) && CollectionUtils.isEmpty(afterArr)) {
            // 删除
            delIds = beforeArr.stream().map(id -> Long.valueOf(id.toString())).collect(Collectors.toList());
        } else if (CollectionUtils.isNotEmpty(beforeArr) && CollectionUtils.isNotEmpty(afterArr)) {
            List<Long> allIds = new LinkedList<>();
            List<Long> beforeIds = beforeArr.stream().map(id -> Long.valueOf(id.toString())).collect(Collectors.toList());
            List<Long> afterIds = afterArr.stream().map(id -> Long.valueOf(id.toString())).collect(Collectors.toList());
            allIds.addAll(beforeIds);
            allIds.addAll(afterIds);
            allIds = allIds.stream().distinct().collect(Collectors.toList());
            for (Long id : allIds) {
                // 新增
                if (!beforeIds.contains(id) && afterIds.contains(id)) {
                    addIds.add(id);
                    // 删除
                } else if (beforeIds.contains(id) && !afterIds.contains(id)) {
                    delIds.add(id);
                }
            }
        }
    }

    public static void main(String[] args) {
        JSONArray beforeArr = new JSONArray();
        beforeArr.add("1");
        beforeArr.add("2");
        beforeArr.add("3");
        JSONArray afterArr = new JSONArray();
        List<Long> addIds = new LinkedList<>();
        List<Long> delIds = new LinkedList<>();
        compareJSONArrays(beforeArr,afterArr,addIds,delIds);
        System.out.println(addIds);
        System.out.println(delIds);
    }

复制代码

上面的代码非常简单,就是判断两个JSONArray之间的差异,如果在beforeArr中存在但在afterArr中不存在,就把id存进delIds,反之则存进addIds。

由于我需要两个返回值,addIds和delIds,所以我从外部传进方法,由于List是引用类型,所以我在方法内部设置值,在方法结束的时候,值还是会存在。

有问题的代码如下

if(CollectionUtils.isEmpty(beforeArr)&&CollectionUtils.isNotEmpty(afterArr)){
   // 新增
   addIds = afterArr.stream().map(id -> Long.valueOf(id.toString())).collect(Collectors.toList());
} else if(CollectionUtils.isNotEmpty(beforeArr)&&CollectionUtils.isEmpty(afterArr)){
   // 删除
   delIds = beforeArr.stream().map(id -> Long.valueOf(id.toString())).collect(Collectors.toList());
}
复制代码

在判断新增,删除的时候我直接将JSONArray转成List并赋值给addIds和delIds。

重点:在java中是不存在引用传递的,只存在值传递。即使你传递的是一个对象时,也只是传递该对象一个引用的副本。

虽然在方法上使用基本类型和string类型时我们会去注意这个问题,但是在传递对象时却容易忽略掉这个问题,所以传递对象时不要轻易的改变该对象的引用。

文章分类
后端
文章标签