Java Collection s.emptyList()の注意事項


たまたま見つけたパートナーがCollection.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に要素を追加することもありますが、Collection.empyList方法が戻ってくるのは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は静的内部クラスであり、AbstrayListと同様に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方法も直接的に一つのIndexOutOfBounds Exceptionを投げ出していることが見られます。addを書き換える方法がないなら、親のAbstractListのadd方法を見てください。

public boolean add(E e) {
  add(size(), e);
  return true;
}
 
public void add(int index, E element) {
  throw new UnsupportedOperationException();
}
直接的に投げ出したUsupportedOperation Exceptionの異常が見られます。また、EmptyListクラスに戻っても、対外的に提供されるいくつかの方法が、その使用範囲を明確に制限している。
Collection s.emptyList()に対して、またはCollection.EMPTY_LISTは、空いているリストのマーク(frozenが通っていると想像できる空List)として使用したほうがいいです。添削の操作はしないでください。もしプログラムの中のいくつかの分岐ロジックがこのような例に戻ったら、テストの時にカバーされていません。生産環境でこの分岐ロジックに行ったら、面倒くさいです。
締め括りをつける
ここで、Java Collection s.emptyList()の注意事項についての文章を紹介します。Java Collection.emptyList()の注意事項は以前の文章を検索してください。または下記の関連記事を引き続きご覧ください。これからもよろしくお願いします。