Я пытаюсь объединить/объединить два массива 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();
}
Во время выполнения я получаю сообщение об ошибке. Почему тогда это не найдено во время компиляции?




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