在查看jdk1.8的ArrayList的源码时,发现这个注释,在查找各种资料后发现这是个bug号,可以通过以下链接查看bug的详细信息以及修复情况!
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6260652
前提知识准备:
package com.tsing0520.list; public class FatherCla { public void print(){ System.out.print("FatherCla."); } } package com.tsing0520.list; public class SonCla extends FatherCla{ public void print(){ System.out.print("SonCla."); } } package com.tsing0520.list; import org.junit.Test; public class MyTest { @Test public void test001(){ SonCla son = new SonCla(); FatherCla f = son; //class com.tsing0520.list.SonCla System.out.println(f.getClass()); f.print(); //SonCla. } }
创建子类的实例,向上转型后调用的是被子类覆盖的方法。
通过测试代码理解为什么需要额外添加判断:
代码段1--正确的情况
@Test public void test002(){ List<String> tempList = java.util.Arrays.asList("123") ; System.out.println(tempList.getClass());// class java.util.Arrays$ArrayList List<String> list = new java.util.ArrayList<>(tempList); System.out.println(list.getClass());// class java.util.ArrayList Object[] listArray = list.toArray(); System.out.println(listArray.getClass());// class [Ljava.lang.Object; listArray[0] = new Object(); }
代码段2--使用java.util.Arrays$ArrayList的toArray()的情况
@Test public void test003(){ List<String> tempList = java.util.Arrays.asList("123") ; System.out.println(tempList.getClass());// class java.util.Arrays$ArrayList //List<String> list = new java.util.ArrayList<>(tempList); //System.out.println(list.getClass());// class java.util.ArrayList //Object[] listArray = list.toArray(); Object[] listArray = tempList.toArray(); System.out.println(listArray.getClass());// class [Ljava.lang.String; listArray[0] = new Object(); //java.lang.ArrayStoreException }
代码段3--错误情况
@Test public void test004() { String[] strArray = { new String() }; Object[] objArray = strArray; System.out.print(objArray.getClass()); //class [Ljava.lang.String; objArray[0] = new Object();// java.lang.ArrayStoreException }
代码段4
@Test public void test005() { Object[] objArray = new Object[4]; Object obj1 = 1; System.out.print(obj1.getClass()); //class java.lang.Integer objArray[0] = obj1; objArray[0] = new Object(); }
java.util.ArrayList 和 java.util.Arrays$ArrayList的toArray()的实现如下:
java.util.Arrays.asList(T...)
// 方法的全限定名:java.util.Arrays.asList(T...) // 返回值: java.util.List<T> @SafeVarargs @SuppressWarnings("varargs") public static <T> List<T> asList(T... a) { return new ArrayList<>(a); // java.util.Arrays.ArrayList.ArrayList<T>(T[]) }
java.util.Arrays.ArrayList<E>
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable { private static final long serialVersionUID = -2764017481108945198L; private final E[] a; @Override public Object[] toArray() { return a.clone(); } //........ }
java.util.ArrayList.toArray()
// java.util.ArrayList.toArray() public Object[] toArray() { return Arrays.copyOf(elementData, size); }
java.util.Arrays.copyOf(T[], int)
// java.util.Arrays.copyOf(T[], int) @SuppressWarnings("unchecked") public static <T> T[] copyOf(T[] original, int newLength) { return (T[]) copyOf(original, newLength, original.getClass()); }