数组是协变的,可具体的,泛型是不可变的,且可被擦除的!!

原创
2017/04/14 11:20
阅读数 193

1.数组是协变的,如果girl是man的子类型,那么数组类型Girl[]就是Man[]的子类型,所以这就使得此向上转型是成立的。

Object[] objects=new Man[size];  
  
Man[] girls=new Girl[size];  
  

数组在编译时表示法可能是抽象的,而在运行时表示法往往一定是具体的,包含更多的信息。

因为向上转型总是安全的。

编译时数组是Object的(抽象的),而运行时数组是Man(具体的)。

编译时数组是Man的(抽象的),而运行时数组是Gir(具体的)。

Object类是所有其他类的父类,那么Object数组可以装入任何对象,编译时,向Object数组里装入任何对象都是不受检查的,而在运行时Man数组只能装入Man对象及其子类。

2.数组是具体化的(reified),而泛型在运行时是被擦除的(erasure)。数组是在运行时才去判断数组元素的类型约束,

而泛型正好相反,在运行时,泛型的类型信息是会被擦除的,只有编译的时候才会对类型进行强化。

Java泛型是编译器泛型,是一种语法,生成的二进制代码中是没有泛型的,jvm感受不到泛型。java的泛型编译生成二进制代码的时候,进行了类型的擦除,放入集合的实际上是object类型,从集合中获取对象的时候 获取的是object类型, 然后进行了强制类型转换,转换成实际的类型。

objects[0]="我是字符串不是女孩,我不能放在这里"; //代码是合法的,但是确实不安全的,会抛出ArrayStoreException异常。

泛型是不可变的:对于任意两个不同的类型Type1与Type2,List<Type1>与List<Type2>不存在继承关系。泛型在编译时强化它们的类型信息,在运行时丢弃它们的元素类型信息。在运行时,泛型里的元素类型都是Object,所以向List<Long>加入String在运行时是合法的,但是无法通过编译。

一般来说,数组和泛型不能很好的混合使用。如果你发现自己将它们混合起来使用,并且得到了编译时错误或者警告,你的第一反应就应该是用列表代替数组。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部