Java Collection toArray 踩坑

Question

笔者在使用java.util.Set的toArray方法时,发现报了java.lang.ClassCastException异常,一时比较纳闷。类似源码如下:

1
2
3
4
5
6
7
8
9
10
11
public void testSetToArray() {
Set<String> set = new HashSet<String>();
set.add("First");
set.add("Second");
set.add("Third");
String[] setArr = (String[]) set.toArray(); // 异常抛出
for (String s : setArr) {
System.out.println(s);
}
}

Solution

在发现该异常后,就去查看了Collection接口的JavaDoc,看方法介绍就是将集合元素按照数组的方式返回,乍一看确实没什么问题,但是在Collection还看到一个重载方法,定义如下:

1
2
3
4
5
public interface Collection<E> extends Iterable<E> {
Object[] toArray();
<T> T[] toArray(T[] a);
}

仔细看无参的toArray方法返回就明白了,该方法返回的是Object[],若显式的Cast就会因为类型不为Object而出现问题,而另一个重载方法是采用的泛型定义,就不会有这个问题,我们重写一下刚刚有问题的代码:

1
2
3
4
5
6
7
8
9
10
11
public void testSetToArray() {
Set<String> set = new HashSet<String>();
set.add("First");
set.add("Second");
set.add("Third");
String[] setArr = set.toArray(new String[0]);
for (String s : setArr) {
System.out.println(s);
}
}

这下问题就解决了,Java提供的集合是很方便,但在使用时也要注意,比如toArray这个方法,使用的姿势不对,编译器也没有提示,最后在运行时才会暴露出来。所以强烈建议使用泛型toArray方法去转换。

坚持原创技术分享,您的支持将鼓励我继续创作!