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