HashSet c = new HashSet();
c.add("a");c.add("b");
c.add("c");c.add("d");
Object[] aw = c.toArray();
String[] ar=(String[])aw;
for(int i=0; i<ar.length;i++)
System.out.println(ar[i]);
编译可以通过,但是一运行会抱错
java.lang.ClassCastException
at SimpleCollection.main(SimpleCollection.java:12)
Exception in thread "main" 请问哪里错了?应该怎么改正。谢谢
c.add("a");c.add("b");
c.add("c");c.add("d");
Object[] aw = c.toArray();
String[] ar=(String[])aw;
for(int i=0; i<ar.length;i++)
System.out.println(ar[i]);
编译可以通过,但是一运行会抱错
java.lang.ClassCastException
at SimpleCollection.main(SimpleCollection.java:12)
Exception in thread "main" 请问哪里错了?应该怎么改正。谢谢
改成:
Object[] aw = c.toArray(new String[0]);
不可以这么搞。
“String是个Object”,不代表“String[]就是个Object[]”,所以不见得一定可以cast。你应该这样:
String[] ar=(String[])awc.toArray(new String[0]);
for(int i=0; i<ar.length;i++)
System.out.println(ar[i]);
但程序的作者或许更清楚其内部元素的更具体的类型,因此,HashSet类提供了toArray的另一个重载版本,允许用户指定一种比Object[]更具体的数组类型,方法是传递一个用户想要的数组类型的一个数组实例进去,多长都无所谓(因此我们常常使用一个0长度的,毕竟把类型带进去就OK了),于是,toArray内部就会按照你想要的这种类型,给构造一个数组出来。这样构造出来的数组,当然是很安全地被调用者转换回那个实际的类型。
那是因为:它们当初是按两种不同的类型构造出来的。
有一个数组本来就是按String数组来构造的,它永远不可以被插入别的东西(比如一个Integer),即使它被转换成了Object[]也不可以,它在创建时被决定了永远只能放String,它的实际类型也永远是String[](不管目前被转换成了什么),所以你也当然可以把它安全地再转换回String[]。
这里需要注意的就是子类数组可以被转换成父类的数组类型,但数组的实际类型不是子类的类型。而另一个数组当初是作为Object数组来构造的,只是目前碰巧它里边都被塞了些String而已,如果你有兴趣,也完全可以塞一些别的进去,因为任何类的对象都可以往Object数组里塞,这种数组,即使它某个时候里面仅有String,又怎么可以轻易地被允许转换成String数组呢?运行一下下面这个程序,或许你能明白一些。
String[] strArray = {"abc", "def"};try {
String[] strArray2 = (String[])objArray;
} catch (ClassCastException e) {
System.out.println("1: Class Cast exception caught.");
}Object[] objArray2 = (Object[])strArray;
try {
String[] strArray2 = (String[])objArray2;
} catch (ClassCastException e) {
System.out.println("2: Class Cast exception caught.");
}
而且在转换为数组的时候要向下转型(down casting)为什么类型的,比如说是String 类型的,或是其他的类型的