[软构/SC]泛型对象的数组

         复习时看到这样一个句话,“不能创造泛型的数组”,会无法通过编译,进行了简单的实验。

        首先区分一下泛型数组和泛型对象的数组,前者是类似  T[ ] list=new T[3] 待创建的类型是泛型;后者是上面这种样子,创建对象是具体的,但使用了泛型标签。前者可能在泛型对象内需要使用,也不能直接创建,但是可以使用强转。在这篇文章讲解了相关内容 Java泛型总结(二)

        在编译器中进行测试,发现这样写编译器会报错,提示创建泛型数组,查询资料发现,由于类型擦除,java不允许创建泛型对象的数组,第三个理由同第一个一样(上文有泛型L出现才会提示,否则会提示无法识别L);而第二个会提示无法使用<>创建。

ArrayList<String>[] list2=new ArrayList<String>[3];//编译阶段报错:创建泛型数组
ArrayList<String>[] list3=new ArrayList<>[3];//编译阶段报错:无法使用<>创建数组
ArrayList<String>[] list7=new ArrayList<L>[3];//编译阶段:创建泛型数组
ArrayList<String>[] list7=new ArrayList<?>[3];//编译阶段:类型不兼容

         但是,如果抛弃后面的<String>,就可以通过编译,并且正常运行。这是因为我们抛弃了ArrayList的泛型多态,它“退化”成了原始类型,因此不再是泛型对象的数组,此时的ArrayList可以传入任何泛型类型的ArrayList,但是会提示未经检查的转换。然后由于其引用List<String>为一个泛型对象,所以只能传入泛型类型为String的ArrayList,此时的list1[0]就与普通的List无异。

List<String>[] list1=new ArrayList[3];
list1[0]=new ArrayList<>();
//list1[0]<=>List<String> list1=new ArrayList<>()
list1[0].add("ab");
System.out.println(list1[0]);

        而如果我们不为List加上<String>,则其引用也是一个原始类型,会提示"形参化的List的原始使用",这时传入一个具体类型的实例也不会产生影响,与原始使用相同,可以传入任意类型的数据,并且输出[1,ab]。

List[] list1=new ArrayList[3];
list1[0]=new ArrayList<Integer>();
list1[0].add(1);
list1[0].add("ab");
System.out.println(list1[0]);
//运行结果:[1,ab]

         另一种可能被想到的实现方法,进行对数组强转,就像泛型数组的强转一样,同样,创造数组时,编译器会提示未经检查的转换;但是不能将父类强转为子类,这在其他情况也是会报错的。如果不想使用危险的原始类型,就使用通配符<?>并在引用出设置类型,依然不能使用泛型L,会提示无法创建泛型数组。

//List<String>[] list3=(ArrayList<String>[])new List[3]; //强转错误
//List<String>[] list4=(ArrayList<String>[])new ArrayList<L>[3];//编译阶段错误:无法创建泛型数组
List<String>[] list5=(ArrayList<String>[])new ArrayList<?>[3];//可行
list5[0]=new ArrayList<>();
System.out.println(list5[0].size());
//运行结果:0

 总结

        如果一定要使用泛型对象创建数组,可以对使用泛型对象的原始类型(new后面的对象不加类型标签)或通配符(标签使用“?”)进行实例化,有以下几种做法

  1. 引用不设置标签,实例使用原始类型或通配符
  2. 引用设置标签,实例使用原始类型,限制了数组元素的泛型类型
  3. 引用设置标签,实例使用强转,设置为原始类型或通配符标签

         关于原因,主要原理就是泛型的擦除导致不允许创建泛型数组,以及引用和实例、父类和子类的转换关系。学习过程中初步了解了原始类型的概念,以及发现同学问我的是开头这句话的上面一句话。

 

 

 

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值