阿里Java手册剖析-6.5【强制】ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException

990 阅读2分钟

阿里Java开发手册剖析:


【强制】ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异 常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。

先来个demo试试:


    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);
        arrayList.add(5);
        arrayList.add(6);
        arrayList.add(7);

        ArrayList<Integer> list = (ArrayList<Integer>) arrayList.subList(1, 3);
        
       
    }

日志输出如下:

ArrayList的subList方法返回的是一个SubList类型对象:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    public List<E> subList(int fromIndex, int toIndex) {
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList(this, 0, fromIndex, toIndex);
    }
	
    ...
    private class SubList extends AbstractList<E> implements RandomAccess {
        private final AbstractList<E> parent;
        private final int parentOffset;
        private final int offset;
        int size;

        SubList(AbstractList<E> parent,
                int offset, int fromIndex, int toIndex) {
            this.parent = parent;
            this.parentOffset = fromIndex;
            this.offset = offset + fromIndex;
            this.size = toIndex - fromIndex;
            this.modCount = ArrayList.this.modCount;
        }
      ...  
      }

}

修改subList导致原List元素改变

demo:

public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);
        arrayList.add(5);
        arrayList.add(6);
        arrayList.add(7);

        List<Integer> list = arrayList.subList(1, 3);
        System.out.println(" subList is :");
        for (Integer integer : list) {
            System.out.println(" "+integer);
        }
        list.add(0,22);
        System.out.println(" after modify subList: ");
        for (Integer integer : arrayList) {
            System.out.println(" "+integer);
        }
    }

日志输出:

subList is :
 2
 3
 after modify subList: 
 1
 22
 2
 3
 4
 5
 6
 7

看下源码可知SubList的add()会同步到原来ArrayList中:

 
 
 public void add(int index, E e) {
            rangeCheckForAdd(index);
            checkForComodification();
            parent.add(parentOffset + index, e);
            this.modCount = parent.modCount;
            this.size++;
        }