Collections API Design FAQ

Why don't you support immutability directly in the core collection
interfaces so that you can do away with optional operations (and
UnsupportedOperationException)?

This is the most controversial design decision in the whole API. Clearly,
static (compile time) type checking is highly desirable, and is the norm in
Java. We would have supported it if we believed it were feasible.
Unfortunately, attempts to achieve this goal cause an explosion in the size
of the interface hierarchy, and do not succeed in eliminating the need
for runtime exceptions (though they reduce it substantially).

Doug Lea, who wrote a popular Java collections package that did reflect
mutability distinctions in its interface hierarchy, no longer believes it is
a viable approach, based on user experience with his collections package. In
his words (from personal correspondence) "Much as it pains me to say it,
strong static typing does not work for collection interfaces in Java."

...

When all was said and done, we felt that it was a sound engineering compromise
to sidestep the whole [exploding interfaces] issue by providing a very small
set of core interfaces that can throw a runtime exception.

Won't programmers have to surround any code that calls optional
operations with a try-catch clause in case they throw an
UnsupportedOperationException?

It was never our intention that programs should catch these exceptions: that's
why they're unchecked (runtime) exceptions. They should only arise as a result
of programming errors, in which case, your program will halt due to the
uncaught exception.

Discussion

Guideline: Avoid optional clauses in semantic contracts.

Semantic Disagreements

Guideline: Provide semantics compatibility tests for your APIs.

Semantics often don't say what the method will do, but what a method can do

Semantics answer the question: What's the full range of legal behavior for this method?