Java 为什么Arrays.asList(…).toArray().getClass()在JDK 8和JDK 9中给出不同的结果?

Java 为什么Arrays.asList(…).toArray().getClass()在JDK 8和JDK 9中给出不同的结果?,java,java-8,java-9,Java,Java 8,Java 9,为什么以下条件在JDK 8中返回true,而在JDK 9中返回false String[].class == Arrays.asList("a", "b").toArray().getClass() 我想说这是JDK 8中的一个bug,在此之前已经修复了 List.toArray()始终声明为返回Object[](请参阅)-它实际上在特殊情况下返回了String[],这是一个错误。asList返回的List类型为。JDK 8中该类的toArray方法是: @Override public Ob

为什么以下条件在JDK 8中返回
true
,而在JDK 9中返回
false

String[].class == Arrays.asList("a", "b").toArray().getClass()

我想说这是JDK 8中的一个bug,在此之前已经修复了


List.toArray()
始终声明为返回
Object[]
(请参阅)-它实际上在特殊情况下返回了
String[]
,这是一个错误。
asList
返回的
List
类型为。JDK 8中该类的
toArray
方法是:

@Override
public Object[] toArray() {
    return a.clone();
}
但在JDK 9+中,它是:

@Override
public Object[] toArray() {
    return Arrays.copyOf(a, a.length, Object[].class);
}
在这两种情况下,
String[]
被传递到
asList
,但在JDK 8情况下,它被克隆,保留其数组类型(
String[]
),而在JDK 9+中,它是使用
Arrays.copyOf
和显式的新数组类型
Object[]
复制的

这种差异意味着在JDK 8
数组中,asList(“a”,“b”).toArray().getClass()返回
字符串[]
,在JDK 9+中返回
对象[]
,因此在JDK 9+中,表达式的计算结果将为
false

这一变化的原因来自以下动机:

收款文件声称:

collection.toArray()
与“功能相同”吗

但是,
Arrays.asList
的实现并不是这样的:如果使用子类型的数组(例如
String[]
)创建,它的
toArray()
将返回相同类型的数组(因为它使用
clone()
)而不是
对象[]

如果稍后尝试在该数组中存储非字符串(或任何内容),则会引发
ArrayStoreException

因此,进行此更改是为了修复以前的行为


如果这对您来说是一个问题,则相关部门会提供以下解决方案:

如果出现此问题,请重写代码以使用one-arg表单
toArray(T[])
,并提供所需数组类型的实例。这也将消除铸造的需要

String[] array = list.toArray(new String[0]);

那是不对的。该方法始终返回
对象[]
(只需查看其返回类型声明)。它从未违反其声明的类型。相反,它违反了记录在案的运行时行为。区别是一个细微的差别,但也是一个重要的差别。关于这一变化的JDK 9发行说明如下:很有趣的是,很长一段时间以来,它包含了一个针对这个错误报告(从2005年开始)的错误行为的保护,而没有人想到首先修复错误行为,显然……很好,谢谢你的解释。不幸的是,该方法是在GWT RPC 2.6.1的序列化代码中调用的,因此我无法轻松切换到参数化
toArray
重载。
String[] array = list.toArray(new String[0]);