A drawback of Don's approach is that it extends from ArrayList. That may be good enough for now, but what happens when you want to use a different List implementation? You could make a NoNullsLinkedList and a NoNullsCopyOnWriteArrayList, etc, but then you wind up with a bunch of little classes that differ only in their extends clause. It might be better to create a List wrapper that doesn't accept null values. For example:
public class NonNullList<E> extends AbstractList<E> { private final List<E> delegate; public NonNullList(List<E> delegate) { this.delegate = delegate; } @Override public E get(int index) { return delegate.get( index ); } @Override public int size() { return delegate.size(); } @Override public E set(int index, E element) { return delegate.set( index, element ); } @Override public void add(int index, E element) { if( element != null ) { delegate.add( index, element ); } } @Override public E remove(int index) { return delegate.remove( index ); } }
It's more code, but now you have the flexibility of choosing a List implementation when you create the object.
A possible problem is that you can still insert nulls into the underlying List object. Don's approach doesn't have the same limitation.