之前分享会做的泛型总结
泛型类
1 | public class Generic<T> { |
泛型接口
定义一个泛型接口
1 | public interface Generator<T> { |
传入泛型实参时:
定义一个生产器实现这个接口,虽然我们只创建了一个泛型接口Generator
但是我们可以为T传入无数种实参,形成无数种类型的Generator接口
在实现类实现泛型接口时,如已将泛型类型传入实参类型,则所有使用泛型的地方都要替换成传入的实参类型
即:Generator
1 | public class FruitGenerator implements Generator<String> { |
泛型方法
不要混淆返回值为泛型的方法和泛型方法,二者不同
一个真正的泛型方法:
首先在public与返回值之间的
这个T可以出现在这个泛型方法的任意位置
泛型的数量也可以为任意多个,如:
1 | public <T, K> K showKeyName(Generic<T> container) { |
1 | public <T> T showKeyName(Generic<T> container) { |
类中也可以有泛型方法
1 | public class Test1<T> { |
泛型类中的类型参数T与泛型方法中的类型参数T是没有联系的,泛型方法始终以自己定义的类型参数为准
如果静态方法要使用泛型的话,必须将静态方法也定义成泛型方法
1 | public class StaticGenerator<T> { |
通配符
<?>
- 被称作无限定的通配符
- 当<?>存在时,Collection对象失去add( )能力
- 即不能调用与类型有关的方法
<? extends T>
- 被称作有上限的通配符,以T为上界
- 对应集合丧失add( )能力
- 可以通过get( )返回元素,能用T以及T的父类接收
- 只能被T以及T就子类的集合赋值
<? super T>
- 被称作有下限的通配符,以T为下界
- 对应集合可以add( )T以及T的子类
- 可以通过get( )返回元素,但只能用Object接收
- 只能被T以及T的父类的集合赋值
泛型的上下边界添加,必须与泛型的声明在一起
泛型的声明:即在类名后的< >,泛型方法修饰符和返回值之间的< >
类型擦除
1 | List<String> l1 = new ArrayList<String>(); |
类型擦除:泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉
在泛型类被类型擦除的时候,之前泛型类中的类型参数部分如果没有指定上限,如
List
1 | public interface List<E> extends Collection<E> { |
类型擦除后,add()方法等同于 boolean add(Object obj);
1 | List<Integer> ls = new ArrayList<>(); |
可以看到,利用类型擦除的原理,用反射的手段就绕过了正常开发中编译器不允许的操作限制