type
status
date
slug
summary
tags
category
icon
password
为什么需要泛型(Generics)?
- 之前实现过一个 int 类型的MyArrayList,但是现在有一个新的需求?
- 编写支持字符串类型的MyArrayList?
- 编写支持long类型的MyArrayList?
- 编写支持User类型的MyArrayList?
- 未来可能有更多的类型。。。
- 你总不可能每一个类型的MyArrayList都写一遍吧
- 在 java 1.5 之前这种事情是普遍发生的
泛型Generics
- JDK 5引入的新特性
- 语法:<数据类型>,其中数据类型必须是引用类型
- 可用于类,接口,方法中
- 本质:参数化类型
- 数据类型被指定成为一个参数类型
- 好处:
- 提供了编译时类型安全检测机制
- 极大增强Java语言的类型系统和抽象能力
- 泛型类
- 泛型接口
- 泛型方法
Java泛型实现时面临的问题
- 后向兼容:还需要支持原来无泛型的容器吗?
- 不得不这样做:二进制后向兼容性是明确写入Java语言规范的严肃承诺 JDK 1.0 编译出来的 class 文件,JDK19也要支持
- 面临的选择:
- 需要泛型化的容器类型,以前的保持不变,新写一套支持泛型化的代码 — C#的选择
- 直接把已有的类型泛型化(类型擦除) — Java的选择
类型擦除
- 类型擦除式 V.S 具现化式
- 类型擦除带来的问题
- 无法对泛型进行实例判断,没法知道泛型到底属于什么
- 无法创建泛型数组
- 无法创建泛型对象
- 类型擦除之后,通过 signature 保留一些类型信息,通过反射等手段获取
泛型通配符
- 无限定通配符 - ?
- 无限制通配符 ? : List<?> list 表示list可以持有任意类型的元素
- 上界通配符 - ? extends T
- 上界通配符 ? extends T : List<? extends T> list 表示list可以持有T类型的子类元素
- 下界通配符 - ? super T
- 下界通配符 ? super T : List<? super T> list 表示list可以持有T类型的父类元素
PECS原则 - Producer Extends Consumer Super
- Producer Extends
- 从集合中读取类型T的数据(集合是生产者),使用通配符 ?extends T
- Consumer Super
- 往集合中添加类型T的数据(集合是消费者),使用通配符 ?super T