Search code examples
javaarraysobjectintegerwrapper

java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.Integer; Concatenate/Merge/join two Integer[] Array


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?


Solution

  • 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);