Reputation: 135
public abstract class AbstractCollection<E> implements Collection<E> {
public boolean add(E e) {
throw new UnsupportedOperationException();
}
The method add(E e)
is not made abstract but made to throw an exception whenever the abstract class is extended. What is the benefit of following this approach? Had the method been made abstract it would have made it mandatory to override and saved some confusion.
Upvotes: 2
Views: 939
Reputation: 50061
Throwing an UnsupportedOperationException
is the standard behavior if you try to modify any collection that is unmodifiable. For example, it is thrown by all of the mutative methods of the classes returned by the Collections.unmodifiable wrappers (of which there are currently eight), such as Collections.unmodifiableList
, and by the immutable Collections.emptyList
, and by all of their iterators.
So, AbstractCollection.add(E)
throws this exception simply to make it easier to implement unmodifiable collections, by providing a useful default behavior. You will see the same behavior implemented in all of these methods too:
(Additionally, the exception is thrown by default by many methods that do not throw it deliberately, but which call methods that do, such as AbstractList.clear()
).
Had the method been made abstract it would have made it mandatory to override and saved some confusion.
Maybe, but there are lots of places where unmodifiable behavior is wanted, so it can be convenient to have a default implementation. It also encourages unmodifiable collections to throw the exception consistently; otherwise someone might implement an add
method by having it do nothing rather than throw the exception, and that would be more confusing.
When you want a modifiable collection, simply look at the doc for the Abstract*
base class that you extended, which will always say which additional methods you need to override. For example, AbstractCollection
says:
To implement an unmodifiable collection, the programmer needs only to extend this class and provide implementations for the
iterator
andsize
methods. (The iterator returned by theiterator
method must implementhasNext
andnext
.)To implement a modifiable collection, the programmer must additionally override this class's
add
method (which otherwise throws anUnsupportedOperationException
), and the iterator returned by theiterator
method must additionally implement itsremove
method.
Upvotes: 3
Reputation: 15844
Not all collections are mutable. This default implementation makes it easy to implement immutable collections.
Upvotes: 1
Reputation: 13596
The answer's in the Javadoc:
If a collection refuses to add a particular element for any reason other than that it already contains the element, it must throw an exception (rather than returning false). This preserves the invariant that a collection always contains the specified element after this call returns.
The idea is that if the method executes successfully, you know that the element is in the collection.
Upvotes: 0