При доступе к Sublist возникает исключение ConcurrentModificationException после десериализации XML - PullRequest
0 голосов
/ 18 мая 2018

Я использую XStrem-1.4.4 для сериализации и десериализации XML.Я пытаюсь создать подсписок объекта ArrayList, как показано в фрагменте кода ниже:

import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.XStream;

public class TestClass {

public static void main(String[] args) {

    List<String> someList = new ArrayList<String>();

    someList.add("String1");
    someList.add("String2");
    someList.add("String3");

    List<String> someSubList = someList.subList(0, 2);

    for (String string : someSubList)
    {
        System.out.println(string);
    }

    System.out.println("=====================================");

    XStream xstr = new XStream();
    String subListXML = xstr.toXML(someSubList);

    System.out.println(subListXML);
    System.out.println("=====================================");

    @SuppressWarnings("unchecked")
    List<String> subList = (List<String>) xstr.fromXML(subListXML);

    for (String string : subList)
    {
        System.out.println(string);
    }
}

}

Когда я запускаю этот код с JAVA 7, я получаю

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1169)
    at java.util.ArrayList$SubList.listIterator(ArrayList.java:1049)
    at java.util.AbstractList.listIterator(AbstractList.java:299)
    at java.util.ArrayList$SubList.iterator(ArrayList.java:1045)
    at com.test.TestClass.main(TestClass.java:36) 

Но это работаетхорошо с JAVA 6.

Я обнаружил, что при работе с JAVA 7 создается следующая структура XML:

<java.util.ArrayList_-SubList>
  <parent class="list">
    <string>String1</string>
    <string>String2</string>
    <string>String3</string>
  </parent>
  <parentOffset>0</parentOffset>
  <offset>0</offset>
  <size>2</size>
  <outer-class reference="../parent"/>
</java.util.ArrayList_-SubList>

, тогда как при работе с JAVA 6 создается структура:

<java.util.RandomAccessSubList>
    <l class="list">
      <string>String1</string>
      <string>String2</string>
      <string>String3</string>
    </l>
    <offset>0</offset>
    <size>2</size>
    <expectedModCount>3</expectedModCount>
</java.util.RandomAccessSubList>

Как говорит specs

Семантика списка, возвращаемого этим методом, становится неопределенной, если вспомогательный список (т.е. этот список) структурно изменяется в любомкроме как через возвращенный список.(Структурные изменения - это изменения, которые изменяют размер этого списка или иным образом нарушают его таким образом, что выполняемые итерации могут давать неверные результаты.)

Я попытался решить эту проблему, заменив строку

List<String> someSubList = someList.subList(0, 2);

с

List<String> someSubList = new ArrayList<String>(someList.subList(0, 2));

Он прекрасно работает как с JAVA 6, так и с JAVA 7, формируя следующую структуру XML:

<list>
   <string>String1</string>
   <string>String2</string>
</list>

Что я хочу знать, так это почемуне рассматривал создание подсписка как структурную модификацию в случае JAVA 6?

И почему ошибка произошла после десериализации XML, а не до этого в случае JAVA 7?

...