java泛型
一、泛型带来的好处
1. 类型安全。类型错误在编译期间就被捕获到(不会在运行时当作 java.lang.ClassCastException),提高程序的可靠性。
2.消除了代码中许多的强制类型转换,增强了代码的可读性。
3. 泛型是什么不会对对象带来影响。
问题:
定义一个泛型类最后到底会生成几个类,比如 ArrayList 到底有几个类 ?
定义一个泛型方法最终会有几个方法在 class 文件中?
为什么泛型参数不能是基本类型呢?
ArrayList 是一个类吗?
ArrayList 和 List 是什么关系?这几个类型的引用能相互赋值吗?
二、泛型概念
**泛型的本质是参数化类型**
1.泛型基本上都是在编译器这个层次来实现。生成的 java字节码 中不包含泛型中的类型信息
( 使用泛型时加上类型参数,编译器编译时去掉,这个过程称为类型擦除 )
擦除后变为Obecjt
擦除后变为A
擦除后变为Object
2.泛型没有独立的 Class类对象,单独记录在Class文件的attributes域内
3.静态变量被泛型类的所有实例共享。
4.泛型的类型参数不能用在 java异常处理的 catch语句中。
(异常处理是由 JVM运行时进行的,泛型在编译后对JVM不可见。)
类型擦除的基本过程:
找到用来替换类型参数的具体类(一般 Object),如果指定了类型参数的上界的话,则使用这个上 界。把代码中的类型参数都替换成具体类,同时去掉出现的类型声明,即去掉 <> 的内容。
泛型的实现原理:
不能实现真正的泛型,只能使用类型擦除来实现伪泛型,虽然不会有类型膨胀,但会出现许多新的问题。
保证类型安全:
既然类型擦除了,如何保证我们只能使用泛型变量限定的类型?
答:java编译器是通过先检查代码中泛型的类型,然后再进行类型擦除,在进行编译。
自动类型转换:
因为类型擦除的问题,所有的泛型类型变量最后都会被替换为原始类型(Object)。既然都替换为原始类,那么为什么我们在获取时,不需要进行强制类型转换?
答:编译器生成 class文件中会在你调用泛型方法完成之后返回调用点之前加上类型转换的操作,比如上下文的 get 函数,就在 get方法完成后,jump回原本的赋值操作的指令位置之前加入了强制转换,转换的类型由编译器推导。
泛型参数的继承关系:
根据Liskov(里氏替换原则 )替换原则,子类是可以替换父类的。但是反过来,需要进行强制类型转换,但是编译器并不能保证运行时这种转换是合法的。
引入泛型后类型系统增加了两个维度:一个是类型参数自身的继承体系结构,一个是泛型类或接口自身的继承体系结构。
| 留言与评论(共有 0 条评论) |