java:(String[])List.toArray()给出了ClassCastException

java:(String[])List.toArray()给出了ClassCastException,java,list,classcastexception,toarray,Java,List,Classcastexception,Toarray,以下代码(在android中运行)在第3行中总是给我一个ClassCastException: final String[] v1 = i18nCategory.translation.get(id); final ArrayList<String> v2 = new ArrayList<String>(Arrays.asList(v1)); String[] v3 = (String[])v2.toArray(); final String[]v1=i18nCateg

以下代码(在android中运行)在第3行中总是给我一个ClassCastException:

final String[] v1 = i18nCategory.translation.get(id);
final ArrayList<String> v2 = new ArrayList<String>(Arrays.asList(v1));
String[] v3 = (String[])v2.toArray();
final String[]v1=i18nCategory.translation.get(id);
final ArrayList v2=新的ArrayList(Arrays.asList(v1));
字符串[]v3=(字符串[])v2.toArray();
当v2是对象[0]以及其中有字符串时,也会发生这种情况。
知道为什么吗?

这是因为当你使用

 toArray() 
它返回一个对象[],该对象不能转换为字符串[](即使内容是字符串),这是因为toArray方法只获取

List 
而不是

List<String>

它分配了正确类型的数组(字符串[],大小正确)

这是因为

 toArray() 
它返回一个对象[],该对象不能转换为字符串[](即使内容是字符串),这是因为toArray方法只获取

List 
而不是

List<String>

它分配了正确的数组类型(字符串[]和正确的大小)

您使用了错误的
toArray()

请记住,Java的泛型主要是语法糖。ArrayList实际上并不知道它的所有元素都是字符串

要解决您的问题,请致电。就你而言

String[] v3 = v2.toArray(new String[v2.size()]);

请注意,泛化表单
toArray(T[])
返回
T[]
,因此不需要显式强制转换结果。

您使用的
toArray()错误。

String[] str = new String[list.size()];
str = (String[]) list.toArray(str);
请记住,Java的泛型主要是语法糖。ArrayList实际上并不知道它的所有元素都是字符串

要解决您的问题,请致电。就你而言

String[] v3 = v2.toArray(new String[v2.size()]);
请注意,泛化表单
toArray(T[])
返回
T[]
,因此不需要显式强制转换结果

String[] str = new String[list.size()];
str = (String[]) list.toArray(str);
像这样使用

String[] v3 = v2.toArray(new String[0]); 
像这样使用

String[] v3 = v2.toArray(new String[0]); 
也有把戏,, 请注意,一旦为方法指定了正确的ArrayType,您甚至不需要再强制转换

也有把戏,,
请注意,一旦为方法指定了正确的ArrayType,您甚至不需要再进行强制转换。

@Kaleb-不正确。或者至少这不是最初的原因。
toArray
方法在集合类为泛型之前就存在。这是正确的解决方案,但不是正确的解释。不能将对象[]强制转换为双[],因为它是一种语言功能,仅此而已。这与泛型无关。您可以将对象强制转换为Double,假设它确实是一个Double。因此,从逻辑上讲,可以对数组执行相同的操作,但它不是语言的一部分。若将对象强制转换为Double,将进行运行时检查,以确保该对象实际上是Double。如果将Double强制转换为Object,则不会进行运行时检查,因为Object位于Double的继承层次结构中。在IntelliJ中执行此操作时,我收到一条警告,建议使用
toArray(新字符串[0])
而不是:“在较旧的Java版本中,建议使用预大小的数组,因为创建适当大小的数组所需的反射调用非常缓慢。然而,由于OpenJDK 6的后期更新,这个调用被内部化,使得空数组版本的性能保持不变,有时甚至更好。同时,传递预大小的数组对于并发集合来说是危险的,因为
size
toArray
调用之间可能存在竞争。“@Kaleb-不是真的。或者至少这不是最初的原因。
toArray
方法在集合类为泛型之前就存在。这是正确的解决方案,但不是正确的解释。不能将对象[]强制转换为双[],因为它是一种语言功能,仅此而已。这与泛型无关。您可以将对象强制转换为Double,假设它确实是一个Double。因此,从逻辑上讲,可以对数组执行相同的操作,但它不是语言的一部分。若将对象强制转换为Double,将进行运行时检查,以确保该对象实际上是Double。如果将Double强制转换为Object,则不会进行运行时检查,因为Object位于Double的继承层次结构中。在IntelliJ中执行此操作时,我收到一条警告,建议使用
toArray(新字符串[0])
而不是:“在较旧的Java版本中,建议使用预大小的数组,因为创建适当大小的数组所需的反射调用非常缓慢。然而,由于OpenJDK 6的后期更新,这个调用被内部化,使得空数组版本的性能保持不变,有时甚至更好。同时,传递预大小的数组对于并发集合来说是危险的,因为
size
toArray
调用之间可能存在竞争。“您可能想阅读有关协方差和逆变的内容——如果T是一个用于实例化的工厂方法的接口,该怎么办。@LaceCard-这只与协方差/逆变有非常间接的关系。真正的问题是,这是
toArray()
方法的指定行为的直接结果。您可能想了解协方差和逆变-如果T是一个用于实例化的工厂方法的接口,情况会怎样。@LaceCard-这只是非常间接地与协方差/逆变相关。真正的问题是,这是
toArray()
方法的指定行为的直接后果。请!格式化你的代码!按“ctrl+k”键选择所有代码,或在代码的第一个字母前和最后一个字母前添加“`”。您也可以在编写答案时在顶部的帮助中选择“{}”!请格式化你的代码!按“ctrl+k”键选择所有代码,或在代码的第一个字母前和最后一个字母前添加“`”。您也可以在编写答案时在顶部的帮助中选择“{}”!