说一下你对泛型的理解
泛型可以实现,在使用时才具体指定参数的类型,它可以使用在类、接口、方法中。
泛型和Object相比,有什么优势?
使用 Object 有两个痛点:1、得强制转换;2、没有编译器级别的安全校验;
使用泛型后,不需要强制转换,如果我们指定了类型之后,如果设置的类型不正确,会报错。这是泛型的优势。
介绍一下泛型擦除
Java的泛型其实是伪泛型,仅在语法上支持泛型,在编译的阶段,会进行泛型擦除。简单来说,就是编译时,如果识别到泛型的语法(<>尖括号及其内容),就将其替换成具体的类型。
替换的规则是这样的,如果有设置上下边界,就按上下边界设置具体类型,没有就设置成Object。
泛型为什么不支持基本类型
因为泛型在没有定义边界的时,进行类型擦除后,原始类型会变成Object,而基本类型不是对象,更不会继承于Object,没有多态性(说白了就是不能隐式转成使用时的目标类型),这就是不支持基本类型的根本原因。
说一下泛型的桥接方法(低概率会问到)
桥接方法只出现在子类重写了父类的泛型方法后。
因为父类的泛型方法,在泛型擦除后,会变成一个具体的类型(比如Object)。而子类覆盖父类这个泛型方法后,可能会指定一个具体类型(比如String)。这会导致父类原本 Object 的那个泛型方法没有被实现,这会让父类没了多态性。
具体的影响,就是当我们使用父类API进行统一调用的时候,可能会出现运行时错误。因为入参或者返回的数据,和我们写代码时候预期的不一样,就会出现类型转换的错误。
Java给出的解决方案是,在子类重写了父类的泛型方法后,编译器会自动生成对应的桥接方法。桥接方法的名称、入参、返回值和父类一致,方法内容就是去调用我们重写的方法。
知识点
在JDK5的时候,Java引入了泛型这个特性。
泛型让我们可以实现,在使用时才具体指定参数的类型。
泛型可以使用在类、接口、方法中。
泛型的意义
其实使用 Object ,也可以实现泛型的所有工作。
那为什么还要引入泛型呢?
因为Object 有两个痛点:1、得强制转换。2、没有编译器级别的安全校验。
例子如下:
没有引入泛型前,Java都是使用 Object 来实现类似泛型功能的
在实际开发中,我们经常会定义一个通用的返回结果类,如下:
传统使用 Object
public class CommonResult{
public boolean success = true;
public Object data;
}
使用泛型
public class CommonResult<T>{
public boolean success = true;
public T data;
}
消除转换
使用传统的 Object 的 CommonResult
如下例子可以看到,当我们需要取出 result.data 来使用的时候,是需要进行强制类型转换的。
public static void main(String[] args){
CommonResult result = new CommonRes