这个问题在这里已有答案:
为什么以下条件返回 true 与JDK 8,而它返回 false 与JDK 9?
true
false
String[].class == Arrays.asList("a", "b").toArray().getClass()
asList 返回的 List 类型为Arrays$ArrayList . 该类中JDK 8中的 toArray 方法是:
asList
List
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[] .
String[]
Arrays.copyOf
Object[]
这种差异意味着在JDK 8中 Arrays.asList("a", "b").toArray().getClass() 返回 String[] ,在JDK 9中它返回 Object[] ,因此在JDK 9中,您的表达式将计算为 false .
Arrays.asList("a", "b").toArray().getClass()
这种变化的原因来自JDK-6260652,其动机如下:
Collection文档声称collection.toArray()与函数“相同”至collection.toArray(new Object [0]);但是,Arrays.asList的实现不遵循:如果使用子类型数组(例如String [])创建,其toArray()将返回相同类型的数组(因为它使用clone())而不是一个东西[] . 如果后来尝试在该数组中存储非字符串(或其他),则抛出ArrayStoreException .
所以这个改变是为了修复以前的行为 .
如果这对您来说是一个问题,相关的release note提供了这个解决方法:
如果出现此问题,请重写代码以使用one-arg形式toArray(T []),并提供所需数组类型的实例 . 这也将消除演员阵容的需要 . String [] array = list.toArray(new String [0]);
我会说这是JDK 8中的一个错误,在此之前已经修复了 .
List<T>.toArray() 总是声明为返回 Object[] (参见JavaDoc) - 在特殊情况下它确实返回 String[] 是一个错误 .
List<T>.toArray()
2 回答
asList
返回的List
类型为Arrays$ArrayList . 该类中JDK 8中的toArray
方法是:但在JDK 9中它是:
在这两种情况下,
String[]
都传递给asList
,但在JDK 8的情况下,它被克隆,它保留其数组类型(String[]
),而在JDK 9中,它使用Arrays.copyOf
复制,显式的新数组类型为Object[]
.这种差异意味着在JDK 8中
Arrays.asList("a", "b").toArray().getClass()
返回String[]
,在JDK 9中它返回Object[]
,因此在JDK 9中,您的表达式将计算为false
.这种变化的原因来自JDK-6260652,其动机如下:
所以这个改变是为了修复以前的行为 .
如果这对您来说是一个问题,相关的release note提供了这个解决方法:
我会说这是JDK 8中的一个错误,在此之前已经修复了 .
List<T>.toArray()
总是声明为返回Object[]
(参见JavaDoc) - 在特殊情况下它确实返回String[]
是一个错误 .