为什么要有泛型
在集合中使用泛型
总结:
- 集合接口或集合类在jdk5.0时都修改为带泛型的结构.
- 在实例化集合类时, 可以指定具体的泛型类型
- 指明完以后, 在集合类或接口中凡是定义类或接口时, 内部结构(比如: 方法, 构造器, 属性等)使用到类的泛型的位置, 都指定为实例化的泛型类型. 比如: add(E e) —> 实例化以后: add(Integer e)
- 注意点: 泛型的类型必须是一个类, 不能是基本数据类型, 需要用到基本数据类型的位置, 拿包装类替换
- 如果实例化时没有指明泛型的类型. 默认类型为java.lang.Object类型
指明泛型以后的自然排序写法
上面implements可以实现Comparable<本类>, 然后重新生成实现方法
指明泛型以后的定制排序写法
自定义泛型结构
如何自定义泛型结构: 泛型类, 泛型接口, 泛型方法
泛型类定义,泛型接口就是把class改成interface即可,但是接口没有构造器
泛型类使用
注意子类继承泛型类
- 直接指明泛型, 子类不用泛型的概念, 相当于写死了, 就用Integer这个类型
- 子类也需要泛型
泛型方法
Collection接口中的toArray方法是泛型方法, 注意: 不是方法中使用了泛型类的泛型, 就叫做泛型方法了
泛型方法的声明, 与其是否在泛型类中没有关系, 即不在泛型类中也可以声明泛型方法
泛型方法的定义为: 在方法中出现了泛型的结构, 泛型的参数与类的泛型参数没有任何关系, 换句话说, 泛型方法所属的类是否是泛型类没有任何关系, 在前面需要加上声明使用泛型方法
举例:
泛型方法可以是static的, static需要加在<E>
之前, 原因: 泛型参数是在调用方法时确定的, 并非在实例化类时确定的 区别于泛型类中静态的方法不能用泛型类中的泛型
泛型在继承上的体现
虽然类A 是 类B的父类 但是 G<A>
和G<B>
例如List<A>
与List<B>
不具备子父类关系, 二者是并列关系
补充: 类A是类B的父类, A<G>
和B<G>
例如List<String>
和 ArrayList<String>
就可以子类引用指向父类对象
通配符的使用
通配符?
类A是类B的父类, G<A>
和G<B>
是没有关系的, 二者共同的父类是G<?>
对于 List<?> 就不能向其内部添加数据了, 除了添加null之外 list.add(null)
允许读取数据, 读取的数据类型为Object
extends的那种类型, 可以用父类接收, 不能用子类接收
super的那种类型, 只能用Object来接收