Java中Collections.emptyList()的注意事項(xiàng)
偶然發(fā)現(xiàn)有小伙伴錯(cuò)誤地使用了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方法中可能會(huì)返回一個(gè)"空的List",后續(xù)還可能往這個(gè)List添加元素(或者移除元素),但是沒(méi)有注意Collections.emptyList方法返回的是一個(gè)EMPTY_LIST:
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
它是一個(gè)static final修飾的成員變量,是一個(gè)EmptyList類的實(shí)例:
public static final List EMPTY_LIST = new EmptyList<>();
這個(gè)EmptyList是一個(gè)靜態(tài)內(nèi)部類,和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;
}
}
可以看到這個(gè)EmptList沒(méi)有重寫add方法,并且get方法也是直接拋出一個(gè)IndexOutOfBoundsException異常。既然沒(méi)有重寫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類中,它對(duì)外提供的一些方法也很明顯地限制了它的使用范圍。
對(duì)于Collections.emptyList(),或者說(shuō)Collections.EMPTY_LIST,最好只把它當(dāng)做一個(gè)空列表的標(biāo)識(shí)(可以想象成一個(gè)frozen過(guò)的空List),不要對(duì)其做一些增刪改查的操作。如果程序中的一些分支邏輯返回了這種實(shí)例,測(cè)試的時(shí)候又沒(méi)有覆蓋到,在生產(chǎn)環(huán)境如果走到了這個(gè)分支邏輯,那就麻煩了~
總結(jié)
到此這篇關(guān)于Java中Collections.emptyList()注意事項(xiàng)的文章就介紹到這了,更多相關(guān)Java Collections.emptyList()注意內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java類加載機(jī)制實(shí)現(xiàn)流程及原理詳解
這篇文章主要介紹了Java類加載機(jī)制實(shí)現(xiàn)流程及原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
關(guān)于Spring?Data?Jpa?自定義方法實(shí)現(xiàn)問(wèn)題
這篇文章主要介紹了關(guān)于Spring?Data?Jpa?自定義方法實(shí)現(xiàn)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Spring AOP與代理類的執(zhí)行順序級(jí)別淺析
這篇文章主要介紹了Spring AOP與代理類的執(zhí)行順序級(jí)別,關(guān)于 Spring AOP和Aspectj的關(guān)系,兩個(gè)都實(shí)現(xiàn)了切面編程,Spring AOP更多地是為了Spring框架本身服務(wù)的,而Aspectj具有更強(qiáng)大、更完善的切面功能2023-03-03
Java?Timer與TimerTask類使程序計(jì)時(shí)執(zhí)行
這篇文章主要介紹了Java定時(shí)器中的Timer和TimerTask的原理。Timer主要用于Java線程里指定時(shí)間或周期運(yùn)行任務(wù),它是線程安全的,但不提供實(shí)時(shí)性(real-time)保證。接下來(lái)就跟隨小編一起深入了解Timer和TimerTask吧2022-02-02
java8實(shí)現(xiàn)List中對(duì)象屬性的去重方法
這篇文章主要介紹了java8實(shí)現(xiàn)List中對(duì)象屬性的去重方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
詳解Java實(shí)現(xiàn)多種方式的http數(shù)據(jù)抓取
本篇文章主要介紹了Java實(shí)現(xiàn)多種方式的http數(shù)據(jù)抓取,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。2016-12-12
在Spring Boot中處理文件上傳功能實(shí)現(xiàn)
這篇文章主要介紹了如何在Spring Boot中處理文件上傳,通過(guò)配置文件上傳屬性、創(chuàng)建控制器來(lái)處理上傳的文件,并通過(guò)異常處理器來(lái)管理錯(cuò)誤情況,可以快速實(shí)現(xiàn)文件上傳功能,需要的朋友可以參考下2024-06-06

