Java 基础 - 没明白过的泛型(中)

泛型实现

泛型擦除,即泛型只是在编译期存在,运行时类型全部被转会为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) {

    }
}
posted @ 2021-04-07 21:54  calmbook  阅读(148)  评论(0编辑  收藏  举报