-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
-
None
The java.util.Collections class specification says the following:
<< The "destructive" algorithms contained in this class, that is, the algorithms that modify the collection on which they operate, are specified to throw UnsupportedOperationException if the collection does not support the appropriate mutation primitive(s), such as the set method. These algorithms may, but are not required to, throw this exception if an invocation would have no effect on the collection. For example, invoking the sort method on an unmodifiable list that is already sorted may or may not throw UnsupportedOperationException. >>
At least, for methods called directly on unmodifiable collection wrapper instances, the mutator methods (add, addAll, remove, etc.) always throw UnsupportedOperationException, even if the operation wouldn't actually modify anything. For example,
List<String> unmodList = ... ;
unmodList.addAll(Collections.emptyList());
throws an UnsupportedOperationException even though the addAll() method wouldn't actually add anything.
Given this, it may be worthwhile for the unmodifiable wrappers to **specify** this behavior. This would be a spec-only change. The behavior would remain the same. The spec text quoted above would probably have to be adjusted.
Also, this change would apply only to instance and default methods on those instances. It wouldn't (necessarily) apply to external methods such as the static utilities on Collections. An example would be
Collections.shuffle(Collections.unmodifiableList(Collections.emptyList()))
which doesn't throw UOE. There's no way the List interface can enforce anything here, as the shuffle algorithm is external to the list, and as it happens, shuffle() ends up calling no mutator methods on an empty list.
SeeJDK-8159404 which is a related case having to do with immutable collections from List.of(), Set.of(), Map.of(), etc.
<< The "destructive" algorithms contained in this class, that is, the algorithms that modify the collection on which they operate, are specified to throw UnsupportedOperationException if the collection does not support the appropriate mutation primitive(s), such as the set method. These algorithms may, but are not required to, throw this exception if an invocation would have no effect on the collection. For example, invoking the sort method on an unmodifiable list that is already sorted may or may not throw UnsupportedOperationException. >>
At least, for methods called directly on unmodifiable collection wrapper instances, the mutator methods (add, addAll, remove, etc.) always throw UnsupportedOperationException, even if the operation wouldn't actually modify anything. For example,
List<String> unmodList = ... ;
unmodList.addAll(Collections.emptyList());
throws an UnsupportedOperationException even though the addAll() method wouldn't actually add anything.
Given this, it may be worthwhile for the unmodifiable wrappers to **specify** this behavior. This would be a spec-only change. The behavior would remain the same. The spec text quoted above would probably have to be adjusted.
Also, this change would apply only to instance and default methods on those instances. It wouldn't (necessarily) apply to external methods such as the static utilities on Collections. An example would be
Collections.shuffle(Collections.unmodifiableList(Collections.emptyList()))
which doesn't throw UOE. There's no way the List interface can enforce anything here, as the shuffle algorithm is external to the list, and as it happens, shuffle() ends up calling no mutator methods on an empty list.
See