概念
用于编译期检查,编译时发现类型不一致就会报错,运行时会自动擦除泛型信息。
用字母代替类型,相当于类型的变量。实际使用的时候必须对类型变量赋值才能使用。
1、方法上使用
用<>把类型变量写在方法声明上,然后方法的返回值、参数、方法里面都可以使用该类型变量,变量的类型在传递实参的时候自动赋值成实参的类型。如:
在f方法定义了T、S、U三个类型变量,方法返回值是U,参数是T和S
f("kkk", new Object())调用是自动将T赋值成了java.lang.String,S赋值成了java.lang.Object
一般来说方法返回值不会是一个单独的类型,而是跟参数类型一样,这样调用者才能决定返回参数的类型。这里的U只是举例用。
2、类上使用
用<>把类型变量写在类名后面,然后类里面的成员变量、方法、参数等都可以使用(静态方法和成员变量不能使用),如:
这里List也使用了传入的T类型,相当于将泛型类型进行了传递,从一个类传到另一个类。
继承类的时候也可以对泛型赋值,如:
ps:即使实参有继承关系,泛型类的对象也不能赋值如List list = new arrayList();是错误的,虽然Integer是Object的子类。
通配符
声明一个有泛型类的变量实例时,可以用?代替具体的实参,如:
List> list;
不过创建对象的时候,还是必须写上具体类型,不能是new ArrayList>()等。
?可以表示任何一种类型,因此List、List都可以赋值给List>
这通常用在参数类型是一个泛型类的方法上,如:
f(List> list) {}
这样实参可以传入任何元素类型的List对象。
extends和super限制实参类型
可用在?的后面,如:
extends Number>表示实参只能是Number的子类,
super Integer>表示实参只能是Integer的父类。
extends还可以用在类或者方法的泛型定义上,而super却不能。
如:
ps:没有泛型数组