Java中的泛型

2019/03/30 Java

Java中的泛型 

JDK1.5 引入的一种程序设计语言的特性,其实就是一个语法糖,虚拟机层面是不存在所谓泛型的概念。

意义:

  • 通过泛型的语法定义,编译器可以在编译期提供一定的类型安全检查,过滤掉大部分因为类型不符而导致的运行时异常; 泛型可以让程序代码的可读性更高,对于 JVM 运行时的性能是没有任何影响的。

  • 编译器会在编译期间擦除泛型语法并相应的做出一些类型转换动作

类型擦除

大部分情况下,泛型类型都会以Object 进行替换,而有一种情况则不是。

public class Entity<T extends String> {
    private T name;
}

这种情况的泛型类型,name 会被替换为String 而不再是 Object

返回值为泛型的处理方式

由于类型擦除,返回值为泛型类型的方法都会擦除成 Object类型,当这些方法被调用后,编译器会额外插入一行checkcast指令用于强制类型转换。

泛型不允许创建数组

Java中的数组是协变的,子类数组实例是可以赋值给父类数组实例,数组类型本质上会由虚拟机运行时动态生成一个类型,这个类型除了记录数组的必要属性,如长度,元素类型等,会有一个指针指向内存某个位置,这个位置就是该数组元素的起始位置;子类数组实例赋值父类数组实例,只是父类数组实例的引用指向堆中子类数组,并不会有所冲突。

如果泛型允许这种协变,看看会有什么问题。

ArrayList<Integer> ints = new ArrayList<>();
ArrayList<Number> nums = new ArrayList<>();
nums = ints;
nums.add(12.34);

这个add方法实际上就将一个浮点数放入了整型容器中了,容易造成逻辑混乱,所以泛型不能支持协变。 如果允许泛型创建数组,由于数组的协变性,泛型数组必然也具有协变性,而泛型本身又不允许协变,自然冲突,所以泛型数组也是不允许创建的。

Search

    Table of Contents