1

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
  • 1
    Casting happens during runtime and ClassCastException are always RuntimeExceptions. When you are casting you are basically telling your compiler "trust me bro, i know what kind of object this is better than you" so of course there will be no compile errors. Just like final String string = (String) new Object(); will compile even though the cast makes no sense.
    – user6073886
    Commented Jun 5, 2023 at 9:22

2 Answers 2

3

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);
0
1

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.