在XML反序列化后访问子列表会引发ConcurrentModificationException

时间:2018-05-18 07:37:52

标签: java xstream sublist

我正在使用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。

我发现在创建XML结构后使用JAVA 7时:

<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));

对于遵循XML结构的JAVA 6和JAVA 7框架,它完全正常:

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

我想知道为什么在JAVA 6的情况下它没有将子列表创建视为结构修改?

为什么在XML反序列化之后发生错误而在JAVA 7之前没有发生错误?

0 个答案:

没有答案