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