前言:Java 泛型是从 JDK 1.5才开始引入的,因此为了兼容之前的版本,Java 中的泛型实现采取了「伪泛型」,即在语法上支持放心,但在编译阶段会进行「泛型擦除」,将所有的泛型表示都替换成具体的类型,即其对应的原生类型。
什么是泛型?
泛型就是指在定义一个类、接口或者方法的时候,可以指定类型参数。这个类型参数可以在使用类、接口或者方法时动态指定。
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。
泛型上下限
<?> // 无限制通配符 |
在《Effective Java》中有关于泛型的使用原则,为了获得最大限度的灵活性,要在表示生产者或者消费者的输入参数上使用通配符,使用的规则就是:生产者有上限、消费者有下限。
- 如果参数化类型表示一个
T
的生产者,使用<? extends T>
。 - 如果它表示一个
T
的消费者,就使用<? super T>
。 - 如果既是生产又是消费,那使用通配符就没什么意义了,此时需要的是精确的参数类型。
泛型数组
泛型数组的声明:
List<String>[] list11 = new ArrayList<String>[10]; // 编译错误,非法创建 |
合理使用泛型数组:
public class ArrayWithTypeToken<T> { |
泛型中 EKVT 的含义
- E:
Element
,在集合中使用,因为集合中存放的是元素。 - T:
Type
,Java类。 - K:
Key
,键。 - V:
Value
,值。 - N:
Number
,数值类型。 - ?: 表示不确定的 Java 类型。
- S、U、V: 2nd、3rd、4th types。
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ |
泛型优势
使用泛型的优势:
- 编译时类型检查:在使用泛型时,加入向容器中存入非特定对象是,在编译阶段就会报错。假如不使用泛型,可以向容器中存入任意类型,容易出现类型转换异常。
- 不需要进行类型强制转换:使用泛型后容器可以记住存入容器中的对象类型。
- 代码可读性提升:使用泛型后,很容易得知容器中对象的类型。
泛型擦除
原则
泛型的类型擦除原则是:
- 消除类型参数声明,即删除
<>
及其包围的部分。 - 根据类型参数的上下限推断并替换所有的类型参数为原生态类型:如果类型参数是无限制通配符或没有上下限定,则替换为
Object
;如果存在上下限定,则根据子类替换原则取类型参数的最左边限定类型(即父类)。 - 为了保证类型安全,必要时插入强制类型转换代码。
- 自动产生「桥接方法」,保证擦除类型后的代码仍然具有泛型的「多态性」。
如何擦除?
1)擦除类定义中的类型参数 => 无限制类型擦除
当类定义中的类型参数没有任何限制时,在类型擦除中直接被替换为
Object
,即形如<T>
和<?>
的类型参数都被替换为Object
。
2)擦除类定义中的类型参数 => 有限制类型擦除
当类定义中的类型参数存在限制(上下限)时,在类型擦除中替换为类型参数的上界或者下界,比如形如<T extends Number>
和<? extends Number>
的类型参数被替换为Number
,<? super Number>
被替换为
Object
。
3)擦除方法定义中的类型参数
同擦除类定义中的类型参数。
关于List、List<?>
、List<Object>
的区别
https://segmentfault.com/a/1190000018189575
List
,即原始类型,其引用变量可以接受任何对应List<E>
的参数化类型, 包括List<?>
,并且可以添加任意类型的元素。但其缺点在于不安全性、不便利性、不表述性(不应该使用原生类型的原因)。List<?>
,即通配符类型,其引用变量,同样可以接受任何对应List<E>
的参数化类型,包括List
,但不能添加任何元素,保证了安全性和表述性,但不具有表述性,从中取出的元素时Object
类型,要通过手动转换才能得到原本的类型。List<Object>
,即实际类型参数为Object
的参数化类型,其引用变量可以接受List
,可以添加元素,但不能接受除了其本身外的任何参数化类型(泛型的子类型化原则)。
- https://pdai.tech/md/java/basic/java-basic-x-generic.html
- https://segmentfault.com/a/1190000018189575
- https://www.cnblogs.com/54chensongxia/p/12470672.html