Java中Collections.emptyList()的注意事项
作者:黄智霖-blog 时间:2022-02-28 18:04:54
偶然发现有小伙伴错误地使用了Collections.emptyList()方法,这里记录一下。她的使用方式是:
public void run() {
......
List list = buildList(param);
......
Object newNode = getNode(...);
list.add(newNode);
......
}
public List buildList(Object param) {
if (isInValid(param)) {
return Collections.emptyList();
} else {
......
}
}
buildList方法中可能会返回一个"空的List",后续还可能往这个List添加元素(或者移除元素),但是没有注意Collections.emptyList方法返回的是一个EMPTY_LIST:
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
它是一个static final修饰的成员变量,是一个EmptyList类的实例:
public static final List EMPTY_LIST = new EmptyList<>();
这个EmptyList是一个静态内部类,和ArrayList一样继承自AbstractList:
private static class EmptyList<E>
extends AbstractList<E>
implements RandomAccess, Serializable {
private static final long serialVersionUID = 8842843931221139166L;
public Iterator<E> iterator() {
return emptyIterator();
}
public ListIterator<E> listIterator() {
return emptyListIterator();
}
public int size() {return 0;}
public boolean isEmpty() {return true;}
public boolean contains(Object obj) {return false;}
public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
public Object[] toArray() { return new Object[0]; }
public <T> T[] toArray(T[] a) {
if (a.length > 0)
a[0] = null;
return a;
}
public E get(int index) {
throw new IndexOutOfBoundsException("Index: "+index);
}
public boolean equals(Object o) {
return (o instanceof List) && ((List<?>)o).isEmpty();
}
public int hashCode() { return 1; }
// Preserves singleton property
private Object readResolve() {
return EMPTY_LIST;
}
}
可以看到这个EmptList没有重写add方法,并且get方法也是直接抛出一个IndexOutOfBoundsException异常。既然没有重写add方法,那么看看父类AbstractList中的add方法:
public boolean add(E e) {
add(size(), e);
return true;
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
可以看到直接抛出的UnsupportedOperationException异常。再回到EmptyList类中,它对外提供的一些方法也很明显地限制了它的使用范围。
对于Collections.emptyList(),或者说Collections.EMPTY_LIST,最好只把它当做一个空列表的标识(可以想象成一个frozen过的空List),不要对其做一些增删改查的操作。如果程序中的一些分支逻辑返回了这种实例,测试的时候又没有覆盖到,在生产环境如果走到了这个分支逻辑,那就麻烦了~
来源:https://blog.csdn.net/huangzhilin2015/article/details/115181718
标签:java,collections.emptylist()
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
JAVA包装类及自动封包解包实例代码
2022-10-23 13:28:54
java联调生成测试数据工具类方式
2021-10-12 06:42:17
详解获取Spring MVC中所有RequestMapping以及对应方法和参数
2023-12-09 21:29:17
Mybatis动态SQL foreach标签用法实例
2023-12-25 07:42:46
java数据结构和算法学习之汉诺塔示例
2021-09-28 14:46:18
Android Loop机制中Looper与handler详细分析
2023-01-13 04:40:56
![](https://img.aspxhome.com/file/2023/3/90183_0s.png)
Ubuntu 20.04 下安装配置 VScode 的 C/C++ 开发环境(图文教程)
2021-12-01 16:48:23
![](https://img.aspxhome.com/file/2023/3/123853_0s.png)
Android开发之子线程操作UI的几种方法
2022-08-05 23:17:52
详解SpringBoot 多线程处理任务 无法@Autowired注入bean问题解决
2022-09-19 19:35:17
Android Studio设置或修改Android SDK路径方法
2023-11-07 17:22:10
![](https://img.aspxhome.com/file/2023/0/122240_0s.png)
详解springboot中使用异步的常用两种方式及其比较
2021-06-16 17:43:29
![](https://img.aspxhome.com/file/2023/6/63496_0s.jpg)
Java实现天天酷跑小游戏完整代码(附源码)
2021-08-03 09:43:43
![](https://img.aspxhome.com/file/2023/3/60833_0s.png)
C# 关于LoadLibrary的疑问详解
2023-07-26 23:14:10
Java实现读取项目中文件(.json或.properties)的方法详解
2022-08-12 23:59:10
常用Maven库,镜像库及maven/gradle配置(小结)
2023-11-20 23:44:00
Java使用反射调用方法示例
2022-09-21 16:48:33
详解Java ES多节点任务的高效分发与收集实现
2021-08-03 13:59:02
C#获取鼠标在listview右键点击单元格的内容方法
2023-10-26 12:40:47
Java使用条件语句和循环结构确定控制流(实例)
2022-07-04 04:52:35
JAVA发送HTTP请求的四种方式总结
2023-08-23 20:27:23