学习:泛型

1.什么是泛型

集合容器类在设计阶段/声明阶段不能确定这个容器到底实际存的是什么类型的对象,所以在JDK1.5之前只能把元素类型设计为Object,
JDK1.5之 后使用泛型来解决。因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于这个元素如何保存,如何管理等是确定的,因此此时把元素的类型设计成一个参数,这个类型参数叫做泛型。

Collection<E>, List<E>, ArrayList<E> 这个<E>就是类型参数,即泛型。

泛型:就是一种不确定的数据类型。

泛型可以省略,如果省略,默认泛型是Object类型。

2.使用泛型的好处是什么?

实际上引入泛型的主要目标有以下几点:

    • 类型安全 
      • 泛型的主要目标是提高 Java 程序的类型安全
      • 编译时期就可以检查出因 Java 类型不正确导致的 ClassCastException 异常
      • 符合越早出错代价越小原则(加入泛型的优点:在编译时期就会对类型进行检查,不是泛型对应的类型就不可以添加入这个集合。)
    • 消除强制类型转换 
      • 泛型的一个附带好处是,使用时直接得到目标类型,消除许多强制类型转换
      • 所得即所需,这使得代码更加可读,并且减少了出错机会

与非泛型代码相比,使用泛型有三大优点:更健壮(在编译时进行更强的类型检查)、更简洁(消除强转,编译后自动会增加强转)、更通用(代码可适用于多种类型)

 

3.Java的泛型是如何工作的 ? 什么是类型擦除 ?如何工作?

面试官问我:“泛型擦除是什么,会带来什么问题?” - 知乎 (zhihu.com)

  1. 类型检查:在生成字节码之前提供类型检查
  2. 类型擦除:所有类型参数都用它们的限定类型替换,包括类,变量,方法(类型擦除)
  3. 如果类型擦除和多态性发生了冲突时,则在子类中生成桥方法解决
  4. 如果调用泛型方法的返回类型被擦除,则在调用该方法时插入强制类型转换
  5. 「Java 路线」| 泛型(含Kotlin) - 简书 (jianshu.com)

类型擦除:

 

4.为什么擦除后,反编译还是看到类型参数 T

 

泛型中所谓的类型擦除,其实只是擦除Code 属性中的泛型信息,在类常量池属性(Signature属性、LocalVariableTypeTable属性)中其实还保留着泛型信息,这也是在运行时可以反射获取泛型信息的根本依据,我在第 4 节说

5.Java中List和原始类型List之间的区别?

原始类型和带参数类型< Object >之间的主要区别:在编译时编译器不会对原始类型进行类型安全检查,却会对带参数的类型进行检查,通过使用Object作为类型,可以告知编译器该方法可以接受任何类型的对象,比如String或Integer
这道题主要考察点在于对泛型中原始类型的正确理解,他们之间的第二点区别是,你可以把任何带参数的类型传递原始类型List,但却不能把List< String >传递给接受List< Object >方法,因为会产生编译错误

 

上界通配符 < ? extends E>

上届:用 extends 关键字声明,表示参数化的类型可能是所指定的类型,或者是此类型的子类。

下界通配符 < ? super E>

下界: 用 super 进行声明,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至 Object

在类型参数中使用 super 表示这个泛型中的参数必须是 E 或者 E 的父类。

6.Array中可以用泛型吗?


这可能是java泛型面试中最简单的一个了,当然前提是你要直到Array事实上并不支持泛型,这也是为什么Joshua Bloch在Effective java一书中建议使用List来代替Array,因为List可以提供编译期的类型安全保证,而Array却不能

 

因为这样做会破坏类型安全

(7 封私信) java为什么不支持泛型数组? - 知乎 (zhihu.com)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值