泛型实现
泛型擦除,即泛型只是在编译期存在,运行时类型全部被转会为Object,也就是说泛型只能当个Object用,除非用上下边界,例如 T extends Number
,那么最后会得到的类型是Number
泛型的主要作用,在没明白过的泛型(上)提到过:
- 编译期
类型检查 + 返回值强转 - 运行期
对某些情况(我在编译加载类的时候就能确定泛型类型的),我可以在反射时拿到具体的泛型参数类型,参考Spring的监听器机制
泛型类,泛型接口
在我看来,泛型类和泛型接口比较类似,他们的最终作用都是靠方法体现的(即编译检查 + 返回强转)
比如说:
List<String> list = new ArrayList<>();
list最终还是靠list.get()等方法体现出泛型的作用
泛型接口也是一样,例如Comparator<T>
但需要注意的泛型的方法并不是泛型方法
泛型方法
泛型方法和泛型类的方法是两个概念,泛型方法是独立于类而存在的,所以即使只是一个普通的类也可以定义泛型方法。
并且静态方法不允许使用类的泛型,所以静态方法需要使用泛型时必须使用泛型方法。
语法:先声明要用的泛型,然后参数,返回值随便你用
public static <T> T createInstance(Class<T> clazz) {
try {
return clazz.newInstance();
} catch (Exception e) {
}
return null;
}
泛型与继承
记住两种情况即可
类型已知
比如说Spring的监听器
class MyListener extends ApplicationListener<StartedEvent>
类型未知
即自己具体时什么类型,还是得靠使用方使用的时候才知道。
比如有这样一个场景:
我定义了一个Dao接口,在BaseMapper中写了一下每个Mapper公用的方法,最后具体的Mapper进行继承(结合了类型已知的继承)
public interface Dao<T> {
void add(T model);
}
// 自己本身还是个泛型
public abstract class BaseMapper<T> implements Dao<T>{
// 一些通用的方法
}
// 结合上面的类型已知情景
public class UserMapper extends BaseMapper<User> {
@Override
public void add(User model) {
}
}