inconsistency between ArrayList.modCount and logic of ArrayList::addAll
Stuart Marks
stuart.marks at oracle.com
Wed May 8 22:31:43 UTC 2019
On 5/8/19 7:44 AM, Pavel Rappo wrote:
> We will certainly hear from Stuart on this very soon.
Heh.
On 5/8/19 5:55 AM, Сергей Цыпанов wrote:
> javadoc for AbstractList.modCount is described as
>
>> The number of times this list has been <i>structurally modified</i>.
>> Structural modifications are those that change the size of the
>> list, or otherwise perturb it in such a fashion that iterations in
>> progress may yield incorrect results.
>
> However when we execute this
>
> ------------------------
> ArrayList<Object> objects = new ArrayList<>();
> boolean result = objects.addAll(Collections.emptyList());
> ------------------------
>
> modCount is 1, not 0 while result is false. I.e. returned value claims the list is not modified, but the inner state of the same list demonstrates the opposite.
I think Pavel has the right point here, which is whether modCount should be
incremented if the list is *actually* modified or whether an *attempt* to modify
it is made. On the one hand, a strict reading seems to indicate incrementing
only actual modifications. However, if the goal is to catch programming errors,
then incrementing on any modification *attempt* seems preferable.
I described this as "state-dependent" behavior in a message in this recent thread:
https://mail.openjdk.java.net/pipermail/core-libs-dev/2019-April/059708.html
https://mail.openjdk.java.net/pipermail/core-libs-dev/2019-May/059979.html
Briefly, consider code like
for (Object obj : objects) {
...
objects.addAll(getAdditionalObjects());
...
}
This is clearly bad code because it modifies the list during iteration. We want
ConcurrentModificationException to be thrown regardless of whether
getAdditionalObjects() returns an empty collection.
In general, the incrementing of modCount (and the consequential throwing of CME)
is an approximation. We usually want to it catch as many errors as feasible, but
not at the cost of unreasonable performance or code complexity.
s'marks
More information about the core-libs-dev
mailing list