泛型方法的理解
泛型方法的关键就在于参数化类型,使得一个方法可以不止作用于一种类型。
例子1 : 打印不同类型的泛型方法
类型T 写于返回值之前
@Test
public void testGenericMethod() {
print("1", "2", "3"); // 打印string
print(1, 2, 3); // 打印int
print(1.0, 2.0, 3.0); // 打印float
}
private <T> void print(T... objs) {
for (T obj : objs) {
log.info(obj.toString());
}
}
例子2 :静态泛型方法写法
public static <T> void print(T t){
}
例子3:泛型类和接口
public class Test<T> { T field1; }
public interface Iterable<T> { }
泛型方法的边界
任意类型过于广泛了,有时候希望限定类型的范围可以使用通配符如下:
- 上边界 <? extends Animal>, 要求是 <= Animal
- 下边界 <? super Animal>, 要求是 >= Animal
泛型的擦除
泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除,
- 没有规定上下界,则擦除为Object类型
- T extends 上界,则擦除为上界的类型
重要例子
List<String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass());
PECS原则
- extends Fruit,producer
- super Apple, consumer 解释 在1中表示的是所有以Fruit为上界的子类型,因此get总是可以返回Fruit f = get(), 而set没办法,因为不确定是哪一种Fruit子类型 在2中表示的是Apple所有父类型,所以可以set(Apple类型)进去,但是不能get,因为不能确定是哪种父类型。