泛型
为什么要有泛型
集合容器类在设计阶段/声明阶段不能确定这个容器到底实际存的是什么类型的对象,所以在JDK1.5之前只能把元素类型设计为object,JDK1.5之后使用泛型来解决。因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于这个元素如何保存,如何管理等是确定的,因此此时把元素的类型设计成一个参数,这个类型参数叫做泛型。Collection<E>,List<E>,ArrayList<E> 这个<E>就是类型参数,即泛型
所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量、创建对象时) 确定 (即传入实际的类型参数,也称为类型实参,
从JDK1.5以后,Java引入了“参数化类型 (Parameterized type)”的概念,允许我们在创建集合时再指定集合元素的类型,正如: List<String>,这表明该List只能保存字符串类型的对象。
JDK1.5改写了集合框架中的全部接口和类,为这些接口、类增加了泛型支持而可以在声明集合变量、创建集合对象时传入类型实参
泛型的使用:
-
jdk5.0新增的特性
-
在集合中使用泛型:
总结:1.集合接口或集合类在jdk5.0时都修改为带泛型的结构
2.在实例化集合类时,可以指明具体的泛型类型
3.指明完以后,在集合类或接口中凡是定义类或接口时,内部结构使用泛型的位置都指定为该类型
4.注意点:泛型类型必须是类,不是基本数据类型。需要用到基本类型的位置,使用包装类
5.如果实例化的时候没有指定泛型。默认类型为java.lang.Object类型。 -
如何自定义泛型结构:泛型类、泛型接口、泛型方法
以泛型类举例:
public class Order<T>{
String orderName;
int orderId;
//类的内部结构就可以使用类的类型
T orderT;
public Order(){
T[] arr = (T[])new Object[10];
};
public Order(String orderName,int orderId,T orderT){
this.orderName = orderName;
this.orderId = orderId;
this.orderT = orderT;
}
}
由于子类在继承带泛型的父类时,指明了泛型类型。则实例化子类对象时,不需要指明泛型。
静态方法中不能使用类的
泛型
class Father<T1, T2> {
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son1 extends Father {// 等价于class Son extends Father<Object,Object>{}
// 2)具体类型
class Son2 extends Father<Integer, String> {}
// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2> extends Father<T1, T2> (){}
// 2)部分保留
class Son4<T2> extends Father<Integer, T2> {}
泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系。换句话说,泛型方法所属的类是不是泛型没有关系,泛型方法可以是static,泛型参数是在调用方法时确定的,并非在实例化类的时候确定的。
1.泛型在继承方面的体现
虽然类A时类B的父类,但是G<A> 和 G<B>不具备子父类关系,二者是并列关系
类A是类B的父类,A<G> 是B<G>的父类
2.通配符的使用
通配符:?
类A是类B的父类,G<A>和G<B>是没有关系的,二者共同的父类是:G<?>
//添加:对于List<?>就不能向其内部添加数据。除了添加null以外
//获取(读取):允许读取数据,读取的数据类型为Object
通配符指定上限:上限:extends:使用时指定的类型必须是继承某个类,或者实现某个接口,即<= G<? extends A>可以作为G<A>和G<B>的父类的,其中B是A的子类
通配符指定下线:使用时指定的类型不能小于操作的类,即>= G<? super A>可以作为G<A>和G<B>的父类的,其中B是A的父类可以加数据加入A以及A的子类

浙公网安备 33010602011771号