为什么Arrays.asList(...)。toArray().getClass() 在 JDK 8 和 9 中给出了不同的结果?
为什么以下条件随 JDK 8 一起返回,而与 JDK 9 一起返回?true
false
String[].class == Arrays.asList("a", "b").toArray().getClass()
为什么以下条件随 JDK 8 一起返回,而与 JDK 9 一起返回?true
false
String[].class == Arrays.asList("a", "b").toArray().getClass()
返回的类型是 Arrays$ArrayList
。该类上的 JDK 8 中的方法是:List
asList
toArray
@Override
public Object[] toArray() {
return a.clone();
}
但在JDK 9+中,它是:
@Override
public Object[] toArray() {
return Arrays.copyOf(a, a.length, Object[].class);
}
在这两种情况下,a 都被传递给 ,但在 JDK 8 情况下,它被克隆,它保留其数组类型 (),而在 JDK 9+ 中,它被复制为与显式的新数组类型 。String[]
asList
String[]
Arrays.copyOf
Object[]
这种差异意味着在 JDK 8 中返回,在 JDK 9+ 中返回 ,因此在 JDK 9+ 中,表达式的计算结果将为 。Arrays.asList("a", "b").toArray().getClass()
String[]
Object[]
false
此更改的原因来自JDK-6260652,其动机是:
“集合”文档声称
collection.toArray()
在功能上相同”
collection.toArray(new Object[0]);
但是,的实现并不遵循以下条件:如果使用子类型的数组(例如)创建,它将返回相同类型的数组(因为它使用),而不是 .
Arrays.asList
String[]
toArray()
clone()
Object[]
如果以后尝试在该数组中存储非字符串(或其他任何内容),则会抛出 。
ArrayStoreException
因此,进行此更改是为了修复以前的行为。
如果这对您来说是一个问题,相关的发行说明会提供以下解决方法:
如果出现此问题,请重写代码以使用 one-arg 形式 ,并提供所需数组类型的实例。这也将消除对铸件的需求。
toArray(T[])
String[] array = list.toArray(new String[0]);
我会说这是JDK 8中的一个错误,之前已经修复了。
List<T>.toArray()
总是被声明为返回(参见JavaDoc) - 它在特殊情况下实际上返回是一个错误。Object[]
String[]