泛型
1. 对加入集合的数据类型进行约束,提高了安全性
2. 不用做专门的数据类型转换,就可以直接使用从集合取出来的对象,效率高
在类定义中使用泛型
1. 在类名后面跟上 <泛型列表> 表示该类所使用的使用泛型,具体是什么类型在编译的时候确定
2. 可以在属性定义时使用
3. 也可以当做返回值
public class Generic01 {
public static void main(String[] args) {
Person<String, Integer> person = new Person<>("Test");
System.out.println(person.getS());
}
}
class Person<E,V> {
E s;
V v;
public Person(E s) {
this.s = s;
}
public E getS() {
return s;
}
public void setS(E s) {
this.s = s;
}
}
运行结果:
泛型使用的注意事项
1. 泛型只能填入引用类型,且在类创建的时候进行指定
2. 指定泛型类型后,可以传入该泛型的子类类型
3. 前面引用声明泛型,后面构造方法就可以不用再次声明泛型(钻石表达式)
4. 如果不声明泛型,默认填入Object
5. 使用泛型的数组,不可以初始化,因为类型不能确定,编译器不知道要开多大空间
6. 静态方法不能使用泛型,因为静态方只和类相关,在类加载的时候对象还没有创建,JVM不能确定泛型的具体类型
7. 接口和方法也适用泛型机制。可以传入不同类型的参数进入参数列表中
泛型继承和通配
1. 泛型不具备继承性
2. <?> 表示支持任意泛型
3. <? extends A> 表示支持 A 类及 A 类的子类,规定了泛型的上限
4. <? super A> 表示支持 A 类及 A 类的父类,规定了泛型的下限
public class Generic02 {
public static void main(String[] args) {
List<Object> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
List<AA> list3 = new ArrayList<>();
List<BB> list4 = new ArrayList<>();
List<CC> list5 = new ArrayList<>();
printCollection1(list1);
printCollection1(list2);
printCollection1(list3);
printCollection1(list4);
printCollection1(list5);
// printCollection2(list1); 不是 AA 的子类
// printCollection2(list2); 不是 AA 的子类
printCollection2(list3);
printCollection2(list4);
printCollection2(list5);
printCollection3(list1);
// printCollection3(list2); 不是 AA 的父类
printCollection3(list3);
// printCollection3(list4); 不是 AA 的父类
// printCollection3(list5); 不是 AA 的父类
}
// List<?> 表示任意泛型类型都可以接受
public static void printCollection1(List<?> c) {
for (Object object : c) {// 通配符,取出时,就是Object
System.out.println(object);
}
}
// ? extends AA 表示 上限,可以接受 AA 或者 AA 的子类
public static void printCollection2(List<? extends AA> c) {
for (Object object : c) {
System.out.println(object);
}
}
// ? super AA 表示 下限,可以接受 AA 或者 AA 的父类
public static void printCollection3(List<? super AA> c) {
for (Object object : c) {
System.out.println(object);
}
}
}
class AA {
}
class BB extends AA {
}
class CC extends BB {
}