приведение объекта[] к массиву ссылочного типа в java
в реализации универсального стека используется следующая идиома и работает без каких-либо проблем
public class GenericStack<Item> {
private int N;
private Item[] data;
public GenericStack(int sz) {
super();
data = (Item[]) new Object[sz];
}
...
}
однако, когда я пытаюсь выполнить следующее, это вызывает ClassCastException
String[] stra = (String[]) new Object[4];
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
Как вы это объясните?
4 ответов
кастинг new Object[4]
до String[]
не работает, потому что Object[]
- это не String[]
, так как Object
не String
.
первый пример работает, потому что стирания типа. Во время выполнения параметр typeItem
было стерто до Object
. Однако он также потерпел бы неудачу, если бы вы попытались назначить массив reifiable типу, например, если data
не private
:
String[] strings = new GenericStack<String>(42).data;
это аналогично бросит ClassCastException
, потому что на самом деле Object[]
будет брошен в String[]
.
из-за дженерики стирания типа массив элементов становится массивом объектов эффективно. Поэтому тип совпадает. Но когда вы делаете это с конкретной строкой типа, это не так. стирание типов не применяется и ничего не получается.
Я думаю, что если ссылка на класс объекта указывает на любой дочерний объект класса, такой как класс String или любой другой класс, только мы можем привести ссылку на класс объекта к этому конкретному классу (который мы создали и назначили объекту класса ref) и назначить ссылку на него. и если мы создадим прямой объект класса Object (как вы упомянули), это не сработает.
пример:
Object[] obj = new String[4];
String[] stra = (String[]) obj;
выше код не будет генерировать любой Исключение ClassCastException.
надеюсь, что это помогает
Я думаю, что это лучший ответ на этот вопрос:
" строка[] не является объектом [], что немного противоречит интуиции. Вы сталкиваетесь со сценарием "банан-это фрукт", но "список бананов-это не список фруктов"."
Ref:https://stackoverflow.com/a/1018774/847818
из того же вопроса, Как бросить:
String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);
или
String[] stringArray = Arrays.asList(objectArray).toArray(new String[objectArray.length]);