请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

波波老师好,我想问一个创建泛型数组强制转换的问题。

Exception in thread “main” java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
at First.main(First.java:26)
在波波老师的介绍后,写作业用到了这个Object[]强制转换为E[],但是不知道为什么运行的时候会报这个 类型转换错误。我觉得跟您讲的数组中用到的差不多呀?
ps:这个小算法是我的作业,用来删除顺序表中从index开始的amount个元素。。如果我把返回值弄成Object[]的话 后边也相应的改成Object[],就可以正常输出了。但是这样数组就不是原来的类型了,就逃避开了这里的问题。。
图片描述

正在回答 回答被采纳积分+3

1回答

liuyubobobo 2018-10-12 05:19:51

问题没有出在你的第4行,而是在20行。简单地说,返回的newArray是Object[]类型,而不是Integer[]类型。你的代码和我的课程中的代码的区别在于,我的课程中的代码,从来不会返回一个泛型数组,只会返回一个泛型值。而泛型值和泛型数组,在Java编译器的处理上,有巨大的差异。Java可以自动把泛型值转换成对应的类型,但无法把一个泛型数组自动转换成对应类型的泛型数组。


这不是什么出色的语言特性,在我看来完全属于java语言的坑!要知道,泛型这种语言特性是在Java 5以后才有的,而不是在Java语言设计之初就支持的一种原生语言特性,可能是这个原因,导致Java语言在一些高级特性的使用上(不仅仅是泛型),其实是很不流畅的。。。


Anyway,如果你想返回的是一个泛型数组,到底要怎么做?


1)不使用Java的内置数组,而是自己包装一个MyArray,返回一个新的MyArray。代码类似这样:

public MyArray<E> deleteFrom(MyArray<E> array, int index){
    MyArray<E> newArray = new MyArray<E>(array);
    newArray.remove(index);
    return newArray;
}


2)如果使用Java的内置数组,就需要明确告诉这个函数E是什么类型,比如这样:

public E[] deleteFrom(E[] arr, Class<E> clazz){
   // 复制了一份 newArray
    E[] newArray = (E[]) Array.newInstance(clazz, arr.length);
    for(int i = 0; i < arr.length; i ++)
        newArray[i] = arr[i];
    
    // 进行你的逻辑 
    // ...
    
    return newArray;
}


此时,调用应该是这样的:

Integer[] res = first.deleteFrom(arr, Integer.class);


加油!:)

2 回复 有任何疑惑可以回复我~
  • 提问者 慕虎3444883 #1
    老师,其实我有一点点..似懂非懂。
    您说出错的原因应该是因为我返回了泛型数组,而Java不会自动把泛型数组转换成对应类型吧。我感觉方法2不管怎么样,返回的也是泛型数组吧..对我来说,这看起来好像有点矛盾。还有就是...总感觉自己懂得不透彻,为什么老师写的1和2就ok了呢,和错误的代码相比避免了哪些错误呢。我有点感觉,但是就是没有get到精髓? 麻烦老师给我拆洗拆洗好嘛!此外...其实方法2中的语法我都没见过,希望老师可以大概点一下,我好去查一些资料了解一下!
    谢谢波波老师~
    回复 有任何疑惑可以回复我~ 2018-10-12 07:20:25
  • liuyubobobo 回复 提问者 慕虎3444883 #2
    方法2其实返回的是clazz类型的数组,因为使用Array.newInstance构造的时候,显示声明了这个数组中的元素类型是clazz。只不过返回值的类型,由于我们不知道传入的clazz类型是什么,所以用E[]表示。你可以近似地理解成这是一种多态(虽然和严格意义的多态不一样)。你的代码,其实也是因为不知道返回什么类型,所以返回的是Object[]。因为Object是所有类型的父类。get不到这个方法的精髓很正常。因为这本身在我看来,就属于Java的高级语法知识。简单理解,就是Java在处理内建的数组,和处理单独的变量,机制极其不一样。所以,我更建议使用方法1。方法1说白了,就是避开了直接使用Java内置数组,而将他们包裹在类中。返回值变成了单独的类,而非数组:)
    回复 有任何疑惑可以回复我~ 2018-10-12 07:29:02
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信