Java中list集合的clean()方法滥用引发的bug

做的是电商系统,主系统生成订单后,分别加入到不同的队列中给另外的三个子系统来异步处理,订单和商品是一对多的关系,在实际测试中,发现其中有一个子系统从队列中获取到的订单实体中,商品列表一直为空,子系统的开发人员一直说是获取不到值导致。因为这个问题,测试一直没通过,不得已只能打日志,反复排查。最后发现在这个子系统中,从队列拿到订单实体后,商品列表是不为空的,但是在执行了一个方法后,该订单实体类的商品就为空了。定位到问题后,调试这个方法,后来发现,整个方法的逻辑都是没问题的,只是在方法的最后,对传入的参数列表执行了clean()的操作。

因为实际项目的业务场景比较复杂,在这里就设计一个简单的例子来实际说明。定义一个City 的实体类和Country的实体类

public class City {

private Integer id;

private String name;

//省略了set和get方法

}

public class Country {

private Integer id;

private String name;

private List<City> listCity; //Country和City是一对多的关系

//省略了set和get方法

}

然后写测试类运行:

public class Test {

public static void main(String[] args) {

City city1=new City();

city1.setId(1);

city1.setName("广州");

City city2=new City();

city2.setId(2);

city2.setName("上海");

List<City> listCity=new ArrayList<>();

listCity.add(city1);

listCity.add(city2);

Country country=new Country();

country.setId(1);

country.setName("中国");

country.setListCity(listCity);

getCity(country.getListCity());

System.out.println("list size:"+country.getListCity().size());

}

public static void getCity(List<City> listCity){

listCity.clear();

}

}

运行该程序,运行结果是:list size:0

而如果把getCity方法中listCity.clear()注释掉,则运行结果为:list size:2

这正是导致项目出现那个bug的原因,其实一般来说,除非已经确定没有程序用到该集合,否则一般不会在方法的最后执行clear()操作。

知道这个原因后,现在来分析为什么调用这个方法后会导致这个后果。查看JDKclean()源码:

通过读源码发现,当调用clean()后,会将集合中的数据全部移走,并且将集合中长度置为0。也就是说该方法调用后,集合会变为空。

微信扫一扫
关注java高高手

原文地址:https://www.cnblogs.com/javagaogaoshou/p/8594431.html

时间: 2024-10-03 23:04:09

Java中list集合的clean()方法滥用引发的bug的相关文章

Java中List集合排序的方法 比较器的使用 根据学生对象数序 语文 英语成绩总和进行sort排序

package com.swift; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Scanner; public class Test2_ObjectIO { @SuppressWarnings("unchecked") public static void main(Strin

java中Set集合的遍历方法

S儿童集合的遍历: 第一种:for增强循环 Set<String> set = new HashSet<String>(); for (String str : set) {      System.out.println(str);} 第二种:迭代器遍历 Iterator<String> it = set.iterator();while (it.hasNext()) {  System.out.println(it.next);} 第三种:用的比较少(主要用于泛型的

将java中数组转换为ArrayList的方法实例(包括ArrayList转数组)

方法一:使用Arrays.asList()方法 1 2 String[] asset = {"equity", "stocks", "gold", "foreign exchange","fixed income", "futures", "options"}; List<String> assetList = Arrays.asList(asset);

菜鸟日记之 java中的集合框架

java中的集合框架图 如图所示:java中的集合分为两种Collection和Map两种接口 可分为Collection是单列集合和Map的双列集合 Collection单列集合:继承了Iterator接口所以具有了iterator()方法 ,该方法返回一个Iterator<T>,这个接口具有 HasNext (),next(),remove()3个方法可以在实现类里完成实现. hasNext():判断是否有下一个元素 cusor是当前的操作下标 next():读取下一个元素 remove(

java中的集合操作类(未完待续)

申明: 实习生的肤浅理解,如发现有错误之处,还望大牛们多多指点 废话 其实我写java的后台操作,我每次都会遇到一条语句:List<XXXXX> list = new ArrayList<XXXXX>(); 但是我仅仅只是了解,list这个类是一个可变长用来存储的对象实例的类,我甚至觉得这个List对象可以理解成数组,但是却又与java中咱们正常理解的数组很多的不同,比如说,他的长度可以随着需要自动增长,比如说,实例化一个List类就和咱们声明数组的时候是不一样的! 今天的实习生活

java中TreeSet集合如何实现元素的判重

1 /* 2 看一下部分的TreeSet源码.... 3 public class TreeSet<E> extends AbstractSet<E> 4 implements NavigableSet<E>, Cloneable, java.io.Serializable 5 { 6 private transient NavigableMap<E,Object> m; 7 //NavigableMap继承SortedMap, 二者都是接口,在TreeMa

为什么Java中有些接口没有任何方法

由于Java不支持多重继承,即一个类只能有一个父类,为了克服单继承的缺点,Java语言引入了接口这一概念.接口是抽象方法定义的集合(接口中也可以定义一些常量值),是一种特殊的抽象类.接口中只包含方法的定义,没有方法的实现.接口中的所有方法都是抽象的.接口中成员的作用域修饰符都是public,接口中的常量值默认使用public static final修饰.由于一个类可以实现多个接口,因此通常可以采用实现多个接口的方式来间接的达到多重继承的目的. 在Java语言中,有些接口内部没有声明任何方法,也

Java中的equals和hashCode方法

本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法. equals()和hashCode()方法是用来在同一类中做比较用的,尤其是在容器里如set存放同一类对象时用来判断放入的对象是否重复.这里我们首先要明白一个问题: equals()相等的两个对象,hashcode()一定相等,equals()不相等的两个对象,却并不能证明他们的h

java中各种集合的用法和比较

一,java中各种集合的关系图 Collection       接口的接口     对象的集合 ├ List             子接口         按进入先后有序保存   可重复 │├ LinkedList    接口实现类     链表     插入删除   没有同步   线程不安全 │├ ArrayList     接口实现类      数组     随机访问   没有同步   线程不安全 │└ Vector        接口实现类       数组