public static void main(String[] args) {
test();
}
}
执行输出:
class java.util.ArrayList
Exception in thread "main" java.lang.ArrayStoreException: java.lang.Object
class [Ljava.lang.Object;
class java.util.Arrays$ArrayList
at io.kzw.advance.csdn_blog.ConcurrentTest.test(ConcurrentTest.java:25)
class [Ljava.lang.String;
at io.kzw.advance.csdn_blog.ConcurrentTest.main(ConcurrentTest.java:34)
Java的泛型是伪泛型,使用不当就会造成这种问题,编译期间没问题,但是执行期报错。
最主要的原因其实是list.toArray()实现方式不一样,导致返回的数组真实类型不一样:
// java.util.Arrays$ArrayList的toArray实现
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size)
return Arrays.copyOf(this.a, size,
(Class<? extends T[]>) a.getClass());
System.arraycopy(this.a, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
// java.util.ArrayList的toArray实现
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
/**
* 同步方法,获取指定位置的元素
*/
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
// 通过索引从数组中找到该元素并返回
return elementData(index);
}
/**
* 获取某元素的位置
*/
public int indexOf(Object o) {
return indexOf(o, 0);
}
/**
* 同步方法,获取某元素的位置
*/
public synchronized int indexOf(Object o, int index) {
// Vector可以存储null值
if (o == null) {
// 从有效元素中查找第一个null值
for (int i = index ; i < elementCount ; i++)
if (elementData==null)
return i;
} else {
// 从有效元素中查找第一个该对象
for (int i = index ; i < elementCount ; i++)
if (o.equals(elementData))
return i;
}
// 没有找到返回-1
return -1;
}
/**
* 同步方法,获取某元素在数组中最后出现的位置
*/
public synchronized int lastIndexOf(Object o) {
return lastIndexOf(o, elementCount-1);
}
/**
* 同步方法,从指定位置向前遍历数组查找元素
*/
public synchronized int lastIndexOf(Object o, int index) {
if (index >= elementCount)
throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
if (o == null) {
for (int i = index; i >= 0; i--)
if (elementData==null)
return i;
} else {
for (int i = index; i >= 0; i--)
if (o.equals(elementData))
return i;
}
return -1;
}
/**
* 同步方法,获取指定索引的元素值
*/
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
// 从数组中找到该索引的值
return elementData(index);
}
/**
* 同步方法,返回数组中第一个有效元素的值
*/
public synchronized E firstElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(0);
}
/**
* 同步方法,返回数组中最后一个有效元素的值
*/
public synchronized E lastElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(elementCount - 1);
}
查找元素的速度快,因为是数组实现,直接通过下标就可以定位到元素。
(4) 修改元素
/**
* 同步方法,修改指定位置的元素,并返回旧元素
*/
public synchronized E set(int index, E element) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
// 先拿到旧元素
E oldValue = elementData(index);
// 数组指定位置重新赋值
elementData[index] = element;
// 返回旧元素
return oldValue;
}
修改元素的速度也快,因为是数组实现,定位元素快。