приведение Object[] к массиву ссылочного типа в 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;

Как вы это объясните?


person damon    schedule 14.06.2013    source источник
comment
Строка не наследуется от Item, поэтому приведение невозможно.   -  person Piovezan    schedule 14.06.2013
comment
@Piovezan String и Item не находятся в одной строке.   -  person Bernhard Barker    schedule 14.06.2013
comment
new GenericStack<String>(10) работает, но если вы попробуете String[] stra = new GenericStack<String>(10).getData(); (реализовать соответствующий геттер), произойдет сбой с ClassCastException. Так что на самом деле это не работает, гипс не был сделан волшебным образом.   -  person Arnaud Denoyelle    schedule 14.06.2013
comment
Тем не менее, вы все еще можете использовать Array.newInstance(Class clazz, Integer) для общего создания вашего массива. Пример Array.newInstance(String.class, sz).   -  person Arnaud Denoyelle    schedule 14.06.2013
comment
Item - это не класс, это просто имя универсального типа. В этом смысле дженерики довольно специфичны. Если вы хотите ответить на него, я бы сосредоточился на том, чтобы выяснить, когда универсальные типы заменяются фактическим типом, если бы я был на вашем месте. Это, конечно, не время компиляции   -  person Jan Hruby    schedule 14.06.2013
comment
ArrayList too Комментарии должны содержать не менее 15 символов.   -  person user2336315    schedule 14.06.2013


Ответы (4)


Преобразование new Object[4] в String[] не работает, потому что Object[] не является String[], так же как Object не является String.

Первый пример работает благодаря стиранию типа. Во время выполнения параметр типа Item был стерт до Object. Однако это также потерпит неудачу, если вы попытаетесь присвоить массив реализуемому типу, например, если data не было private:

String[] strings = new GenericStack<String>(42).data;

Точно так же это вызовет ClassCastException, потому что то, что на самом деле является Object[], будет преобразовано в String[].

person Paul Bellora    schedule 14.06.2013

Из-за стирания универсального типа массив элементов фактически становится массивом объектов. Поэтому тип совпадает. Но когда вы делаете это с конкретным типом String, это не так. Стирание типа не применяется и не выполняется.

person Grzegorz Żur    schedule 14.06.2013

Я думаю, что если ссылка на класс объекта указывает на любой объект дочернего класса, такой как класс String или любой другой класс, тогда только мы можем привести ссылку на класс объекта к этому конкретному классу (какой объект мы создали и назначили ссылке на класс объекта) и назначить ссылка на него. и если мы создадим прямой объект класса Object (как вы упомянули), работать не будет.

Пример:

Object[] obj = new String[4];
String[] stra = (String[]) obj;

приведенный выше код не будет генерировать никакого ClassCastException.

Надеюсь это поможет

person vikasgupta    schedule 14.06.2013

Я думаю, что это лучший ответ на этот вопрос:

«Строка [] не является объектом [], что немного нелогично. Вы сталкиваетесь со сценарием «Банан — это фрукт», но со сценарием «Список бананов — это не список фруктов».

Ссылка: https://stackoverflow.com/a/1018774/847818

Из того же вопроса, как бросить:

String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);

or

String[] stringArray = Arrays.asList(objectArray).toArray(new String[objectArray.length]);
person Enrichman    schedule 14.06.2013
comment
Правильным действием здесь может быть просто комментарий к вопросу, говорящий что-то вроде Возможный дубликат. - person Bernhard Barker; 14.06.2013
comment
Возможно, но лично, если ответ на самом деле не тот, я бы дождался отзыва от ОП. Может быть, он попросит чего-то большего и другого. :) - person Enrichman; 14.06.2013
comment
спасибо @Enrichman за ссылку, я получил общий код стека из книги алгоритмов Седжвика .. ваша ссылка помогла мне лучше понять это - person damon; 14.06.2013
comment
-1 Массивы ковариантны (в отличие от дженериков): String[] является Object[]. ClassCastException происходит потому, что Object[] не является String[]. - person Paul Bellora; 14.06.2013