软件编程
位置:首页>> 软件编程>> java编程>> Java中Collections.emptyList()的注意事项

Java中Collections.emptyList()的注意事项

作者:黄智霖-blog  发布时间:2022-02-28 18:04:54 

标签:java,collections.emptylist()

偶然发现有小伙伴错误地使用了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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com