定义:声明中具有一个或者多个 类型参数(type parameter) 的类或者接口,就是 泛型类或者接口 。泛型类和接口统称为 泛型(generic type) 。
每种泛型定义一组 类型形参(formal type parameters) ,这些类型形参有时也被简称为 类型参数(type parameter) ,例如对于 泛型 ( generic type )List<E>而言,List<String>就是一个 参数化的类型(parameterized type) ,String就是对应于 类型形参 (formal type parameters) 的 类型实参(actual type parameter) 。
每个泛型定义一个 原生类型(raw type) ,即不 带任何类型参数的类型名称 ,例如,与List<String>对应的原生类型是List。原生类型就像从类型声明中删除了所有泛型信息一样。实际上原生类型List与Java平台在有泛型之前的接口类型List完全一样。
容器类使用泛型的好处:
虽然使用原生类型是合法的,但不提倡这样做, 因为如果使用原生类型,就失掉了泛型在安全性和表述性方面的所有优势 ;安全性:比如我们可能会不小心把一个java.util.Date实例错误地放进一个原本包含java.sql.Date实例的集合当中,虽然在编译期不会出现任何错误,但在运行期一旦尝试类型转换就会发生ClassCastException, 而泛型原本就是为了避免这种问题而出现的 ;表述性: 不像带有类型实参的泛型即参数化类型那样 ,让人看到 实参 就知道里面的元素E都是什么类型。
泛型的子类型化的原则:List<String>类型是原生类型List的一个子类型,而不是参数化类型List<Object>的子类型
List、List<?>、List<Object>的区别
引用变量的类型 | 名称 | 可以接受的类型 | 能否添加元素 | 安全性 | 便利性 | 表述性 |
---|---|---|---|---|---|---|
List | 原始类型 | 任何对应List<E>的参数化类型, 包括List<?> | 可以添加任意类型的元素 | 无 | 无 | 无 |
List<?> | 通配符类型 | 以接受任何对应List<E>的参数化类型,包括List | 不能添加任何元素 | 有 | 无 | 有 |
List<Object> | 实际类型参数为Object的参数化类型 | 仅可以接受List和其本身类型 | 可以添加任意类型元素 | 有 | 有 | 有 |
可以看到相比参数化类型的List<Object>,List<?>缺点在于不能添加任何元素并且不具有便利性,如果这无法满足功能要求可以考虑使用泛型方法和有边界的通配符。
根据The Java™ Tutorials,原生类型对象可以被赋给参数化类型(包括有界无界通配符参数化类型),同样,参数化类型(包括有界无界通配符参数化类型)对象也能被赋给原生类型