面试时问到关于Java泛型的问题,之前只是大概的了解,现在做一个总结

1、何为泛型,为什么要使用泛型?

泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

2、泛型可以使我们在编译时就检查出程序的错误,可以看以下例子:

 

 

 stringList集合定义的泛型为String类型,但是当stringList.add(1)即为Integer类型时,便会在编译时就会提示错误,编译通不过。

3、泛型只在编译时有效,在运行时便会进行泛型的擦除,在jvm中并不存在泛型,可以看下面的例子:

1 List<String> stringList = new ArrayList<>();
2 List<Integer> integerList = new ArrayList<>();
3 
4 System.out.println(stringList.getClass() == integerList.getClass());  //输出true

4、泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法

5、如何获取泛型的真实类型

如果在父类中想要获取泛型T的类型 ,T.class; T.getClass(); 这两种方法都是无法实现的,因为泛型T不是一个真正的类或者实例,

下面通过反射获得泛型T的真实的类的类型:

package Thread.type_demo;


import java.lang.reflect.ParameterizedType;

@SuppressWarnings("uncheck")
public class Base<T> {

    private Class<T> clazz;


    //通过反射技术获取泛型类的真实类型
    public Base(){

        // 获取当前new的对象的泛型的父类类型
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();// 这里的this代表子类的实例

        // 获取第一个类型参数的真实类型
        this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
        System.out.println("---> clazz : " + this.clazz);
    }

    public static void main(String[] args) {
        User user = new User();
        Role role = new Role();
    }
}
public class User extends Base<User> {

}
public class Role extends Base<Role> {
    
}

运行结果:

posted @ 2020-09-25 12:00  ZERSOG  阅读(153)  评论(0编辑  收藏  举报