【问题标题】:casting Object[] to a reference type array in java将 Object[] 转换为 java 中的引用类型数组
【发布时间】:2013-06-11 02:31:25
【问题描述】:

在通用堆栈的实现中,使用以下成语并且没有任何问题

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;

你怎么解释这个?

【问题讨论】:

  • String 不继承自 Item,因此无法进行强制转换。
  • @Piovezan StringItem 不在同一行。
  • new GenericStack&lt;String&gt;(10) 有效,但如果您尝试 String[] stra = new GenericStack&lt;String&gt;(10).getData();(实现相应的 getter),则会因 ClassCastException 而失败。所以它并没有“真正”起作用,演员阵容并没有神奇地完成。
  • 也就是说,您仍然可以使用Array.newInstance(Class clazz, Integer) 来一般地创建您的数组。示例Array.newInstance(String.class, sz).
  • Item 不是一个类,它只是泛型类型名称。泛型以这种方式非常具体。如果你想回答这个问题,如果我是你,我会专注于找出泛型类型何时被实际类型替换。肯定不是编译时间

标签: java arrays generics classcastexception


【解决方案1】:

new Object[4] 转换为String[] 不起作用,因为Object[] 不是String[],就像Object 不是String

第一个例子是因为type erasure。在运行时,类型参数Item 已被擦除为Object。但是,如果您尝试将数组分配给可具体化的类型,它同样会失败,例如如果 data 不是 private

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

这同样会抛出ClassCastException,因为实际上是Object[] 的内容将被转换为String[]

【讨论】:

    【解决方案2】:

    由于泛型类型擦除 Item 数组有效地变成了 Object 数组。因此类型匹配。但是,当您使用具体类型 String 执行此操作时,它不会。 没有应用类型擦除,它失败了。

    【讨论】:

      【解决方案3】:

      我认为如果 Object 类引用指向任何子类对象,如 String 类或任何其他类,那么只有我们可以将对象类引用强制转换为该特定类(我们创建并分配给 Object 类引用的对象)并为其分配一个引用。如果我们创建 Object 类的直接对象(如您所提到的)将不起作用。

      例子:

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

      以上代码不会产生任何 ClassCastException。

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        我认为这是这个问题的最佳答案:

        “A String[] 不是 Object[],这有点违反直觉。你遇到的是“Banana is-a fruit”而是“List Of Bananas is-not-a List Of Fruit”场景。”

        参考: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]);
        

        【讨论】:

        • 这里的正确操作可能只是对问题的评论,例如“Possible duplicate”。
        • 可能,但就个人而言,如果答案不一样,我会等待 OP 的反馈。也许他会要求更多和不同的东西。 :)
        • 感谢@Enrichman 的链接,我从 sedgewick 的算法书中得到了通用堆栈代码。你的链接帮助我更好地理解它
        • -1 数组是协变的(与泛型不同):String[] isObject[]ClassCastException 正在发生,因为 Object[] 不是 String[]
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-02
        • 2015-05-12
        • 2012-12-30
        • 2018-11-12
        • 2019-06-22
        • 1970-01-01
        相关资源
        最近更新 更多