遇到如下问题:
List<String> list = new ArrayList<String>();
list.add("wang");
list.add("hello");
list.add("world");
// 不能转换成功 抛出classCastexception
String[] listToArray = (String[]) list.toArray();
来分析下源码:
public Object[] toArray() {
int s = size;
Object[] result = new Object[s];
System.arraycopy(array, 0, result, 0, s);
return result;
}
classCastexception异常是类型强制转换出错,换句话说就是String[]不是toArray()返回值的子类。
源码中可以清晰的看到 toArray返回的是Object[],并不是List<String>。
所以toArray() 只适合那种不需要强行转换的情况。【啥情况?】
解决方法:使用toArray(T[] contents)
public <T> T[] toArray(T[] contents) {
int s = size;
if (contents.length < s) {
@SuppressWarnings("unchecked") T[] newArray
= (T[]) Array.newInstance(contents.getClass().getComponentType(), s);
contents = newArray;
}
System.arraycopy(this.array, 0, contents, 0, s);
if (contents.length > s) {
contents[s] = null;
}
return contents;
}
代码:
// I
String[] arr1 = list.toArray(new String[0]);
// II
String[] arr2 = new String[list.size()];
arr2 = list.toArray(arr2);
I:目的只是为了把类型传进去,使得返回的类型还是传进去的类型String
//T[] newArray = (T[]) Array.newInstance(contents.getClass().getComponentType(), s)
II:用给的数组返回数据,不用重新new,效率上有一定提高。
// ADD 2011.8.25
Set<E> 里面的
toArray()
toArray(T[])
最终调用的是java.util.concurrent.CopyOnWriteArrayList
public Object[] toArray() {
Object[] elements = getArray();
return Java6Arrays.copyOf(elements, elements.length);
}
@SuppressWarnings("unchecked")
public <T> T[] toArray(T a[]) {
Object[] elements = getArray();
int len = elements.length;
if (a.length < len)
return (T[]) Java6Arrays.copyOf(elements, len, a.getClass());
else {
System.arraycopy(elements, 0, a, 0, len);
if (a.length > len)
a[len] = null;
return a;
}
}
原理跟ArrayList一样。