List值add异常问题
今天发现一个集合的坑,希望分享一下,顺便自己梳理一下排查的思路.
首先代码如下,红色框的部分报错:
堆栈信息如下:
messagejava.util.AbstractList.add(AbstractList.java:148)@&java.util.AbstractList.add(AbstractList.java:108)@&java.util.AbstractCollection.addAll(AbstractCollection.java:344
这个代码最开始觉得很不可思议,因为repo读出来的数据都是list,clear之后再AddAll为什么会出现这个错呢。
仔细研究了这行代码,发现这个add竟然是抽象类AbstractList报出来的。
原因就是该list不支持add方法,这就奇怪了,难道返回的对象不支持add方法,我们常见的List包括ArrayList,
linkedList, SkipList等等。
所以大胆的推测是返回的一个没有实现add方法的List对象。所以我们开始看获取的list实现。
后来发现这个问题并不是必现的,是当查询出来的结果是空的时候才会出现这个异常。发现底层查询的实现:
返回的是查询底层返回空,就返回Collections.emptyList()。这究竟是怎样一个list呢。
查看其源码实现:
发现其继承了AbstractList但是并未实现add方法。此时才恍然大悟,原来当为空的情况下,返回给上层的list是这个。
针对这种情况,Collections.emptyList()的设计是JDK为了在明确是空集合的时候避免new ArrayList带来的性能消耗问题,大部分情况对性能的敏感度不高的情况下强烈建议返回给上层的空集合尽量避免Collections.emptyList()。可以使用Lists.newArrayList()来构造空集合。