为什么 Arrays.asList(...).toArray().getClass() 在 JDK 8 和 9 中给出不同的结果?
Why does Arrays.asList(...).toArray().getClass() give different results in JDK 8 and 9?
为什么下面的条件 return true
和 JDK 8,而 returns false
和 JDK 9?
String[].class == Arrays.asList("a", "b").toArray().getClass()
我会说这是 JDK 8 中的一个错误,之前的版本已修复。
List<T>.toArray()
总是被声明为 returning Object[]
(见 JavaDoc)——实际上它在 return String[]
一个特殊情况是一个错误。
asList
返回的List
类型是Arrays$ArrayList
。 JDK 8 中 class 中的 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 Arrays.asList("a", "b").toArray().getClass()
returns String[]
和JDK 9+中returns Object[]
, 所以在 JDK 9+ 你的表达式将计算为 false
.
这个变化的原因来自JDK-6260652,动机是:
The Collection documentation claims that
collection.toArray()
is "identical in function" to
collection.toArray(new Object[0]);
However, the implementation of Arrays.asList
does not follow this: If created with an array of a subtype (e.g. String[]
), its toArray()
will return an array of the same type (because it use clone()
) instead of an Object[]
.
If one later tries to store non-Strings (or whatever) in that array, an ArrayStoreException
is thrown.
因此进行此更改是为了修复以前的行为。
如果这对您来说是个问题,相关的 release note 提供了这个解决方法:
If this problem occurs, rewrite the code to use the one-arg form toArray(T[])
, and provide an instance of the desired array type. This will also eliminate the need for a cast.
String[] array = list.toArray(new String[0]);
为什么下面的条件 return true
和 JDK 8,而 returns false
和 JDK 9?
String[].class == Arrays.asList("a", "b").toArray().getClass()
我会说这是 JDK 8 中的一个错误,之前的版本已修复。
List<T>.toArray()
总是被声明为 returning Object[]
(见 JavaDoc)——实际上它在 return String[]
一个特殊情况是一个错误。
asList
返回的List
类型是Arrays$ArrayList
。 JDK 8 中 class 中的 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 Arrays.asList("a", "b").toArray().getClass()
returns String[]
和JDK 9+中returns Object[]
, 所以在 JDK 9+ 你的表达式将计算为 false
.
这个变化的原因来自JDK-6260652,动机是:
The Collection documentation claims that
collection.toArray()
is "identical in function" to
collection.toArray(new Object[0]);
However, the implementation of
Arrays.asList
does not follow this: If created with an array of a subtype (e.g.String[]
), itstoArray()
will return an array of the same type (because it useclone()
) instead of anObject[]
.If one later tries to store non-Strings (or whatever) in that array, an
ArrayStoreException
is thrown.
因此进行此更改是为了修复以前的行为。
如果这对您来说是个问题,相关的 release note 提供了这个解决方法:
If this problem occurs, rewrite the code to use the one-arg form
toArray(T[])
, and provide an instance of the desired array type. This will also eliminate the need for a cast.String[] array = list.toArray(new String[0]);