Java.lang.ClassCastException: класс [Ljava.lang.Object; нельзя привести к классу [Ljava.lang.Integer; Объединить/объединить/объединить два массива Integer[]

Я пытаюсь объединить/объединить два массива Integer[] и сохранить их в другом Integer[]. Но я получаю следующую ошибку во время выполнения.

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)

Мой код такой.

Основной класс.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();
    }

Во время выполнения я получаю сообщение об ошибке. Почему тогда это не найдено во время компиляции?

Кастинг происходит во время выполнения, и ClassCastException всегда является RuntimeExceptions. Когда вы выполняете кастинг, вы в основном говорите своему компилятору: «Поверь мне, братан, я знаю, какой это объект лучше, чем ты», поэтому, конечно, ошибок компиляции не будет. Так же, как final String string = (String) new Object(); будет компилироваться, даже если приведение не имеет смысла.

OH GOD SPIDERS 05.06.2023 11:22
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
1
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Почему тогда это не найдено во время компиляции?

Потому что вы преобразовали результат concatenate в Integer[]. Если бы вы удалили приведение, возникнет ошибка компилятора, говорящая о том, что Object[] (тип возвращаемого значения concatenate) не может быть преобразован в Integer[] (тип concatArray).

Обратите внимание, что Stream.toArray() возвращает экземпляр Object[], а не массив любого типа элементов, содержащихся в потоке. Последнее невозможно из-за стирания типа.

Возвращает:

массив, тип компонента времени выполнения которого Object, содержащий элементы этого потока

Также обратите внимание, что нет необходимости инициализировать concatArray в new Integer[...], если concatenate все равно вернет новый массив.

Чтобы исправить concatenate, одним из способов было бы вызвать перегрузку из toArray с помощью IntFunction:

public static <T> T[] concatenate(T[] hardCodeValus, T[] userValue, IntFunction<T[]> arrayCreator)
{
    return Stream.concat(Arrays.stream(hardCodeValus), Arrays.stream(userValue))
            .toArray(arrayCreator);
}

Использование:

var concatArray = concatenate(hardCodeValus, userValue, Integer[]::new);

java.util.stream.Stream.toArray() возвращает массив, тип компонента среды выполнения которого — java.lang.Object.

Но во время компиляции, в соответствии с сигнатурой метода, вы можете вернуть любой подкласс объекта, который может быть или не быть назначенным из типа java.lang.Integer.

Во время компиляции код является синтаксически правильным в соответствии с сигнатурой метода и типами данных в основном методе.

Фактическая проверка типа происходит во время выполнения в строке concatArray = (Integer[]) StreamsFunc.concatenate(hardCodeValus, userValue);

Таким образом, вы получаете исключение во время выполнения, а не во время компиляции, потому что при выполнении метода конкатенации он фактически возвращает массив объектов.

Другие вопросы по теме