List接口的toArray方法可以把一个结合转化为数组,但是使用不方便,toArray()方法返回的是一个Object数组,所以需要自行转变.

toArray(T[] a)虽然返回的是T类型的数组,但是还是需要传入一个T类型的数组,这也挺麻烦的.我们期望输入的是一个泛型化的list,这样就能转化为泛型数组了.

看代码:

1 importjava.util.Arrays;2 importjava.util.List;3

4 public class Client{5 public static T[] toArray(Listlist){6 T[] t = (T[])newObject[list.size()];7 for(int i=0,n=list.size();i

13 public static voidmain(String[] args) {14 List list = Arrays.asList("A","B");15 for(String str:toArray(list)){//这一句报错16 System.out.println(str);17 }18 }19 }

编译没有任何问题,运行后出现如下异常;

Exception in thread "main"java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

at cn.summerchill.test.Client.main(Client.java:17)

类型转换异常,也就是说,不能把一个Object数组转换为String数组,这段异常包含了两个问题:

1.为什么Object数组不能向下转型为String数组?

数组是一个容器,只有确保容器内的所有元素类型与期望的类型有父子关系时才能转换,Object数组只能保证数组内的元素是Object类型.却不能确保它们都是String的父类型或子类,所以转换失败.

2.为什么是main方法抛出异常,而不是toArray方法?

其实,是在toArray方法中进行的类型向下转换,而不是main方法中,那为什么异常会在main方法中抛出,应该在toArrya方法的   T[] t = (T[])new Object[list.size()] 这段才对啊....

那是因为泛型是类型擦除的,toArray方法经过编译后与如下代码相同:

1 importjava.util.Arrays;2 importjava.util.List;3

4 public class Client{5 public staticObject[] toArray(List list){6 //此处的强制类型没必要存在,只是为了保持与源代码对比

7 Object[] t = (Object[])newObject[list.size()];8 for(int i=0,n=list.size();i

14 public static voidmain(String[] args) {15 List list = Arrays.asList("A","B");16 for(String str:(String[])toArray(list)){17 System.out.println(str);18 }19 }20 }

阅读完此段代码就很清楚了,toArray方法返回后会进行一次类型转换,Object数组转换成了String数组,于是就报了ClassCastException异常了.

Object数组不能转换成String数组,T类型又无法在运行期获得,那该如何解决这个问题呢?

其实要想把一个Object数组转换成为String数组,只要Object数组的实际类型也是String就可以了.

1 public class Client{2 public static voidmain(String[] args) {3 //objArray的实际类型和表面类型都是String数组

4 Object[] objArray = {"A","B"};5 //抛出ClassCastException

6 String[] strArray =(String[])objArray;7

8 String[] ss = {"A","B"};9 //objs的真实类型是String数组,显示类型为Object数组

10 Object[] objs =ss;11 //顺利转换为String数组

12 String[] strs =(String[])objs;13 }14 }

知道了上面,把泛型数组声明为泛型类的子类型

1 importjava.lang.reflect.Array;2 importjava.util.Arrays;3 importjava.util.List;4

5 public class Client{6

7 public static T[] toArray(List list, ClasstClass) {8 //声明并初始化一个T类型的数组

9 T[] t =(T[]) Array.newInstance(tClass, list.size());10 for(int i=0,n=list.size();i list = Arrays.asList("A", "B");17 for (String str : toArray(list,String.class)) {18 System.out.println(str);19 }20 }21 }

通过反射类Array声明了一个T类型的数组,由于我们无法在运行期获得泛型类型的参数,因此就需要调用者主动传入T参数类型.此时,客户端再调用就不会出现任何异常了.

在这里我们看到,一个泛型类(特别是泛型集合)转变为泛型数组时,泛型数组的真实类型不能是泛型类型的父类型(比如顶层类Object),只能是泛型类型的子类型(当然包含自身类型),否则就会出现类型转换异常.

java数组子类型_[改善Java代码]数组的真实类型必须是泛型类型的子类型相关推荐

  1. java 注解应用技巧_改善Java应用程序性能的快速技巧

    java 注解应用技巧 曾经遇到过性能问题吗? 我也是. 如果我的经理再喊一次" faaaaster",我一生都会有听力障碍. 顺便说一句,我能听到所有噪音中的德语发音吗? ;-) ...

  2. java项目----教务管理系统_基于Java的教务管理系统

    java项目----教务管理系统_基于Java的教务管理系统 2022-04-22 18:18·java基础 最近为客户开发了一套学校用教务管理系统,主要实现学生.课程.老师.选课等相关的信息化管理功 ...

  3. java关于泛型的实验代码_[改善Java代码]强制声明泛型的实际类型

    Arrays工具类有一个方法asList可以把一个变长参数或数组变成列表,但是它有一个缺点:它所生成的List长度是不可改变的,而这在我们的项目开发中很不方便. importjava.util.Arr ...

  4. java 代码解析工具_改善 Java 代码质量的工具与方法

    原标题:改善 Java 代码质量的工具与方法 我们可能见过上面的有关代码质量的图片,究竟如何衡量一段代码好坏? 代码质量是什么?为什么它很重要? 作家通过他的著作来讲述了一个清晰的.令人信服的故事.他 ...

  5. 怎么查看java的引用类_一段代码看 Java 引用类型

    Java 中的操作数(不知道叫什么,相对于 bytecode 而言,类似 CPU 的操作码和操作数)分为值类型和引用类型: 值类型就是直接存储最终数值的,如 char, int, float, dou ...

  6. java 字符数组与字符串_用于字符串和数组的5种简单有效的Java技术

    java 字符数组与字符串 Java通常会排在前五种最流行的编程语言中,因此可以理解. 它是一种通用语言,非常容易学习,因为它是一种高级语言,并且可以满足许多用例. 由于这些原因,Java是一门很棒的 ...

  7. java ee 的使用方法_改善Java EE生产支持技能的8种方法

    java ee 的使用方法 参与Java EE生产支持的每个人都知道这项工作可能很困难. 7/24寻呼机支持,多个事件和错误修复(要定期处理),来自客户和管理团队的压力,要求它们尽快解决生产问题并防止 ...

  8. java枚举对象作用_浅析Java编程中枚举类型的定义与使用

    定义枚举类型时本质上就是在定义一个类,只不过很多细节由编译器帮您补齐了,所以某些程度上,enum关键字的 作用就像是class或interface. 当您使用"enum"定义枚举类 ...

  9. java 数组 取部分_在Java中只获取一部分数组?

    在Java中只获取一部分数组? 我在Java中有一个Integers数组,我只想使用它的一部分. 我知道在Python中你可以做类似这个数组[index:]的东西,它从索引中返回数组. 这样的事情在J ...

最新文章

  1. 控制C++的类只能在堆分配或只能在栈分配
  2. 活动文档服务器,服务器 活动
  3. 【NOIP2013模拟联考6】选课
  4. 推荐一款配置中心新贵:Nacos,阿里开源,是真的香!!
  5. 八大编程语言之父:爸爸们节日快乐!
  6. shell脚本如何显示所执行的每一条命令
  7. 项目管理流程图模板分享
  8. Python通过IMAP实现邮箱客户端
  9. android播放器适配,Android开发 MediaPlayer将视频播放时尺寸适配完美
  10. 复现论文常用函数(一)tf.one_hot,tf.train.batch,tf.train.shuffle_batch,数据读取机制,获取文件路径,Bunch等
  11. matlab 写netcdf,写入 netCDF 属性
  12. 苹果8wifi找不到服务器,教大家遇到苹果手机iPhone11搜不到无线网怎么解决
  13. Excel 2010 VBA 入门 087 数据处理之按单列汇总多个工作表
  14. 爬取偶像/私房小姐姐图片--爬虫基础篇
  15. 目前收益比较好的广告联盟和广告方式
  16. python 携程_python-携程爬虫
  17. 【300+精选大厂面试题持续分享】大数据运维尖刀面试题专栏(十五)
  18. 2-1暴力破解原理和测试流程
  19. 【Linux】Linux学习(四)Shell编程
  20. 数据库MySQL(一) 常用查询语句

热门文章

  1. 化工原理(过滤和沉淀)
  2. tornado环境搭建
  3. 岗位内推 | 微软亚洲研究院智能多媒体组招聘计算机视觉算法实习生
  4. 报名 | “智见AI”SpringCamp:物体检测与深度神经网络模型设计
  5. 第四期 | 带学斯坦福CS224n自然语言处理课+带打全球Kaggle比赛(文末重金招募老师!)...
  6. 再来一顿贺岁宴 | 从K-Means到Capsule
  7. 未能加载程序集或它的一个依赖项_英伟达发布kaolin:一个用于加速3D深度学习研究的PyTorch库...
  8. Tomcat【环境搭建 02】Web端403 Access Denied You are not authorized to view this page解决方法(Tomcat 10.2.12 版本)
  9. 【Linux部署】Greenplum数据库6.13.0单机版 [CRITICAL]:-Error occurred: non-zero rc: 1(报错详情+问题处理:内存释放)
  10. 面试官:什么是HTTP连接池?你怎么回答?Feign性能调优之HTTP连接池