泛型类
泛型类(generic class) 就是具有一个或多个类型变量的类。一个泛型类的简单例子如下:
//常见的如T、E、K、V等形式的参数常用于表示泛型,编译时无法知道它们类型,实例化时需要指定。
public class Pair <K,V>{
private K first;
private V second;
public Pair(K first, V second) {
this.first = first;
this.second = second;
}
public K getFirst() {
return first;
}
public void setFirst(K first) {
this.first = first;
}
public V getSecond() {
return second;
}
public void setSecond(V second) {
this.second = second;
}
public static void main(String[] args) {
// 此处K传入了Integer,V传入String类型
Pair<Integer,String> pairInteger = new Pair<>(1, "第二");
System.out.println("泛型测试,first is " + pairInteger.getFirst()
+ " ,second is " + pairInteger.getSecond());
}
}
泛型接口
public interface Generator<T> {
T next();
}
实现类去实现这个接口的时候,可以指定泛型T的具体类型。
public class NumberGenerator implements Generator<Integer> {
@Override
public Integer next() {
return new Random().nextInt();
}
}
泛型方法
具有一个或多个类型变量的方法,称之为泛型方法。
public class GenericMethods {
public <T> void f(T x){
System.out.println(x.getClass().getName());
}
public static void main(String[] args) {
GenericMethods gm = new GenericMethods();
gm.f("字符串");
gm.f(666);
}
}
泛型通配符
我们定义泛型时,经常碰见T,E,K,V,?等通配符。本质上这些都是通配符,是编码时一种约定俗成的东西。当然,你换个A-Z中另一个字母表示没有关系,但是为了可读性,一般有以下定义:
+? 表示不确定的 java 类型
- T (type) 表示具体的一个java类型
- K V (key value) 分别代表java键值中的Key Value
- E (element) 代表Element
通配符通常分三类:
- 无边界通配符,如List<?>
- 上边界限定通配符,如<? extends E>;
- 下边界通配符,如<? super E>;
1 注意:?代表任意类型,实际上可以把它看成是一种具体的类型,比如String,Integer
2 T可以出现在,泛型定义,不能用在泛型的具体指定。
3 ?可以看成是String,所以可以用在方法参数中的泛型指定,实例化时的泛型指定。
4 ?可以看成是Object,但是?的泛型指定,不能放入Object
PECS
- producer extends :用extends定义的泛型T, 取出的时候可以拿到具体类型
- custmor super: 用super定义的泛型T,存入的时候可以确定具体类型
- 处理上述两点 extends和super 无其他区别
总结
- 一定区分泛型的定义,和泛型是使用。
- 泛型定义:在类上,方法上。
- 泛型使用:除了上一条的两点,都是泛型使用,包括实例化的成员变量,方法的参数签名,继承父类中的泛型,实现接口中的泛型等。
- 泛型定义可以用T等不确定的类型
- 泛型使用必须用具体类型或者?来指定所需类型
-
public static <T> T getBean(String name){
return (T)applicationContext.getBean(name);
}
这个定义了泛型方法,但是参数中并没有T。效果是可以返回任意类型,反编译后,在调用方会加上强制转换
网友评论