不能创建参数化的泛型数组

在Java中,我们不能实例化(注意我说的是实例化)一个参数化类型的数组,但是却可以参数化数组本身的类型,也许大家觉得有点绕口,没有关系,我来慢慢解释,并且通过代码,让大家看的更清楚。

第一种情况,不能实例化一个参数化类型的数组,什么叫参数化类型的数组呢,就是这个数组里存储的对象是参数化类型,大家比较熟悉的List<String>就是一个类型参数为String的参数化类型,我们在Java中也称呼它为泛型。来看代码(直接粘贴的代码没有编译器的报错指示,所以我直接截图):

我们发现报错了,报错信息就是Java无法创建参数化类型的数组。

那么为什么Java会禁止我们做这样的事呢,《Thinking in java》一书中指出,由于泛型具有擦除机制,在运行时的类型参数会被擦除,Java只知道存储的对象是一个Object而已,而对于Java的数组来说,他必须知道它持有的所有对象的具体类型,而泛型的这种运行时擦除机制违反了数组安全检查的原则。

那么有其他可以曲线救国的方法吗,注意我之前所说,虽然我们不能实例化一个参数化类型的数组,但是编译器也只是检查实例化而已,而对于创建一个参数化类型数组的引用,却并不会报错。

所以我们可以通过创建一个非参数化类型的数组,然后将他强制类型转换为一个参数化类型数组。即:

然后我们就会发现编译不再提示报错,我们来使用一下看看。

正常传入一个String类型参数的list并不会有任何问题,但当我们传入一个类型参数为Integer的list时编译器却提示我们有错,报错原因是类型不合法,数组期望一个List<String>,我们却传入了List<Integer>,由此我们知道,通过强转型实现的参数化类型数组,Java已经获悉了这个数组在运行时应该持有的具体类型,因此他是一个合法的数组。

这是第一种情况,我们不能实例化参数化类型的数组。

第二种情况,我们可以参数化数组本身的类型。

参数化数组本身的类型,顾名思义,我们不再参数化数组持有的对象的类型,而是将数组应该存储的对象进行参数化,我们来看一个返回一个数组的参数化方法:

在该参数化方法中,我们传入了一个数组,返回该数组本身,唯一的引人注目的地方就是数组中的对象类型为泛型。

我们来简单的测试一下。

其中JR类为我建的一个简单类,重写了toString方法便于查看,而不是让他默认打印对象地址。

下面是运行结果。

我们发现,无论我们传入Integer类型数组或String类型数组或自定义对象数组,该参数化方法总能正确的执行,即数组本身的类型被参数化了,但在运行时,被赋予了具体的类型。

事实上,即使我们能参数化数组本身的类型,我们也不能直接创建一个泛型数组,这在编译时都不被允许。

注意红色波浪线。

我们可以通过创建Object数组然后将其强转型为T[ ]来近似实现我们的目的,但这是没有意义的。

因为在这种情况下,任何Object类型及其子类,也就是除了基本类型之外的所有Java对象都可以放入这个数组中。

通过以上的研究,我们可以发现,想将泛型与数组联系起来使用是一件既危险又容易自讨没趣的苦差事,所以在日常使用中,我们最普遍使用泛型的情况就是与Collection与Map联系使用,以协助我们快速发现错误而不是等到运行时才报出一大串异常。

谢谢大家,今天的泛型数组的相关内容大致就说到这里了,有问题的话大家可以在下面评论区交流哦。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值