RFR: 8079136: Accessing a nested sublist leads to StackOverflowError

Peter Levart peter.levart at gmail.com
Sat May 9 19:02:54 UTC 2015


On 05/09/2015 04:36 PM, Ivan Gerasimov wrote:
> On 09.05.2015 14:15, Doug Lea wrote:
>> On 05/08/2015 02:17 PM, Ivan Gerasimov wrote:
>>>> The spec says "The returned list is backed by this list"
>>>> and "The subclass's set(int, E), get(int), add(int, E), remove(int),
>>>> addAll(int, Collection) and removeRange(int, int) methods all 
>>>> delegate to the
>>>> corresponding methods on the backing abstract list".
>>>> It is possible that no differences could be detected, but it would 
>>>> take
>>>> some effort to prove.
>>> Hm.  Let me try.
>>> We have two options:
>>> 1) Sublist of an arbitrary AbstractList, which is not SubList itself.
>>> 2) Sublist of another SubList.
>> Plus:
>> 3) An arbitrary wrapping of SubList, as seen for example in Collections
>> utilities like synchronizedList:
>>         public List<E> subList(int fromIndex, int toIndex) {
>>             synchronized (mutex) {
>>                 return new SynchronizedList<>(list.subList(fromIndex, 
>> toIndex),
>>                                             mutex);
>>             }
>>         }
>> ... which can define methods relying on the specified full cascade.
> Sorry, I cannot see how wrapping of SubList is different from any 
> other dealing with the sublist's API.
> Shouldn't it remain as before, as long as we preserve the list's 
> behavior?

I think Ivan is right here and this is safe, because SubList and 
RandomAccessSubList can not be overridden outside AbstractList. In a 
chain of sub-lists, there can be runs of consecutive 
[RandomAccess]SubList(s) intermingled with custom implementations that 
can not be SubList subclasses:

SubList at 1 -> SubList at 2 -> CustomSubListA -> CustomSubListB -> SubList at 3 
-> SubList at 4 -> ListImpl

It is guaranteed that SubList.root pointers in above scenario will be 
(see SubList(AbstractList, ...) constructor):

SubList at 1.root == CustomSubListA
SubList at 2.root == CustomSubListA
SubList at 3.root == ListImpl
SubList at 4.root == ListImpl

In order for a sub-list to be skipped with add,get,... invocations, it 
has to be a SubList (see SubList(SubList, ...) constructor). And there 
can be not custom SubList subclasses.

So no invocation of any custom method can be skipped.

Regards, Peter

More information about the core-libs-dev mailing list