Java Empty List Is Broken

The docs for the empty list singleton says something like "The empty list is immutable and serializable."

It is essentially a NullObject implementation for a List Collection.

While #size returns zero, #contains always returns false, and #get always throws an IndexOutOfBoundsException, #add gets no special treatment in the EmptyList class implementation.

This can lead to subtle programmer bugs that are difficult to track down. The programmer can be adding to what he thinks is a regular collection object but not be able to iterate through it or query its contents. Instead, #add should have be redefined to throw an unmodifiable list exception. While some may argue this breaks the LiskovSubstitutionPrinciple, it provides the programmer with immediate feedback (upon the first test run) that she has broken the contract for the use of this collection object.


How does #add not get any special treatment? java.util.Collections#EMPTY_LIST is specified to be immutable. java.util.Collections#unmodifiableList(java.util.List) is a factory method to create unmodifiable, or immutable, lists. Its Javadoc comment specifies that attempts to modify the list result in an UnsupportedOperationException--that's exactly what happens when you call #add on EMPTY_LIST (at least in J2SE SDK 1.4). --OliverKamps

Oliver, the JDK 1.4 source code that I am looking at simply sets the EMPTY_LIST singleton to an instance of EmptyList. Hence, #add does not throw an exception. What am I missing? -- RobertDiFalco

You're missing the fact that EmptyList extends AbstractList, in which #add is defined to throw UnsupportedOperationException. --JuhaKomulainen


Surely this demonstrates the dangers of the NullObject pattern -- not to mention the silliness of the Java "strong" type system. Why does this object exist at all? Why does a list with no elements need its own distinguished object? Could it be because list behavior (like all Java collections) is simply broken? Why not use "null" instead of this object? Could it be because "null" is broken (it is a value, not an object -- there is no way to give it behavior)? Could it possibly be true that the Lisp and Smalltalk communities, who discovered and explored the singular behavior of Nil more than 25 years ago, may have been onto something after all?

Ahem, IfSmalltalkIsSoGoodWhyDoesNobodyUseIt

The EmptyList is not just a CodeSmell -- it is a CodeStench.


The earlier objections don't make sense. I prefer to use empty collections instead of nulls, making checks for null unnecessary. It would be nice if Java let you define null behavior for a class, but that's a more general problem.


The Collections API is known to have various problems (large chunks of it ignore the LSP, it doesn't handle primitives well, it doesn't give you enough data structures, etc) so why don't we start DesigningBetterJavaCollections?


Comments on page:


EditText of this page (last edited October 5, 2014) or FindPage with title or text search