英文:
java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.Integer; Concatenate/Merge/join two Integer[] Array
问题
我正在尝试将两个Integer[]数组连接/合并并存储在另一个Integer[]中。但是我在运行时遇到以下错误。
at AllInOnePack.MainClass.AllInOne.main(AllInOne.java:61)```
我的代码如下。
**Main class.java**
```java
static Integer[] hardCodeValues = {1,2,3,4};
static Integer[] userValues = {1,2,3,4};
concatArray = new Integer[hardCodeValues.length+userValues.length];
concatArray = (Integer[]) StreamsFunc.concatenate(hardCodeValues, userValues);
StreamsFunc.java
public static <T> Object[] concatenate(T[] hardCodeValues, T[] userValues)
{
return Stream.concat(Arrays.stream(hardCodeValues), Arrays.stream(userValues)).toArray();
}
为什么这不是在编译时发现的错误呢?
英文:
I'm trying to concatenate/merge two Integer[] array and store it in an other Integer[]. But I'm getting bellow error at run time.
Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.Integer; ([Ljava.lang.Object; and [Ljava.lang.Integer; are in module java.base of loader 'bootstrap')
at AllInOnePack.MainClass.AllInOne.main(AllInOne.java:61)
My code is like this.
Main class.java
static Integer[] hardCodeValus = {1,2,3,4};
static Integer[] userValue = {1,2,3,4};
concatArray = new Integer[hardCodeValus.length+userValue.length];
concatArray = (Integer[]) StreamsFunc.concatenate(hardCodeValus, userValue);
StreamsFunc.java
public static <T> Object[] concatenate(T[] hardCodeValus, T[] userValue)
{
return Stream.concat(Arrays.stream(hardCodeValus), Arrays.stream(userValue)).toArray();
}
During run time I'm getting the error. Why this is not found in compile time then?
答案1
得分: 3
因为您将 concatenate
的结果转换为 Integer[]
。如果您移除了这个强制转换,编译器会报错,提示无法将 Object[]
(concatenate
的返回类型)转换为 Integer[]
(concatArray
的类型)。
请注意,无参数的 Stream.toArray()
返回的是一个 Object[]
实例,而不是流中包含的元素类型的数组。它不能做到后者,因为由于类型擦除,这是不可能的。
> 返回:
>
> 一个数组,其运行时组件类型为 Object
,包含此流的元素
同时请注意,如果 concatenate
将返回一个新数组,那么将 concatArray
初始化为 new Integer[...]
是不必要的。
要修复 concatenate
,一种方法是使用带有 IntFunction
参数的 toArray
的重载版本:
public static <T> T[] concatenate(T[] hardCodeValues, T[] userValue, IntFunction<T[]> arrayCreator)
{
return Stream.concat(Arrays.stream(hardCodeValues), Arrays.stream(userValue))
.toArray(arrayCreator);
}
用法示例:
var concatArray = concatenate(hardCodeValues, userValue, Integer[]::new);
英文:
> Why this is not found in compile time then?
Because you casted the result of concatenate
to Integer[]
. Had you removed the cast, there will be a compiler error saying that Object[]
(the return type of concatenate
), cannot be converted to Integer[]
(the type of concatArray
).
Note that the parameterless Stream.toArray()
returns an instance of Object[]
, not an array of whatever type of element the stream contains. It can't possibly do the latter because of type erasure.
> Returns:
>
> an array, whose runtime component type is Object
, containing the
> elements of this stream
Also note that it is unnecessary to initialise concatArray
to new Integer[...]
, if concatenate
is going to return a new array anyway.
To fix concatenate
, one way would be to call the overload of toArray
with an IntFunction
:
public static <T> T[] concatenate(T[] hardCodeValus, T[] userValue, IntFunction<T[]> arrayCreator)
{
return Stream.concat(Arrays.stream(hardCodeValus), Arrays.stream(userValue))
.toArray(arrayCreator);
}
Usage:
var concatArray = concatenate(hardCodeValus, userValue, Integer[]::new);
答案2
得分: 1
java.util.stream.Stream.toArray()
返回一个其运行时组件类型为 java.lang.Object
的数组。
但在编译时,根据方法签名,您可以返回 Object
的任何子类,这些子类可以是 java.lang.Integer
类型的子类,也可以不是。
在编译时,代码在方法主体中的方法签名和数据类型方面是语法正确的。
实际的类型检查发生在运行时,即在 concatArray = (Integer[]) StreamsFunc.concatenate(hardCodeValus, userValue);
这一行。
因此,您在运行时会收到异常,而不是在编译时,因为当执行 concatenate
方法时,它实际上返回一个 Object
数组。
英文:
java.util.stream.Stream.toArray() returns an Array whose runtime component type is java.lang.Object.
But at compile time, as per method signature, you can return any subclass of Object which may or may not be assignable from java.lang.Integer type.
At compile time, code is syntactically correct as per method signature and data types in the main method.
Actual type check occurs at runtime at line concatArray = (Integer[]) StreamsFunc.concatenate(hardCodeValus, userValue);
So, you get an exception at Runtime rather than compile time because when concatenate method is executed it actually returns an Object array.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论