第一章深入 Java 泛型【一、泛型的作用与定义】

第一章深入 Java 泛型

  • 一、泛型的作用与定义
    • 1.1 泛型的作用
    • 1.2 泛型的定义
    • 1.3 泛型擦除

一、泛型的作用与定义

1.1 泛型的作用

  • 使用泛型能写出更加灵活通用的代码。

泛型的设计主要参照了 C++ 的模板,旨在能让你写出更加通用化,更加灵活的代码。模板/泛型代码,就好像做雕塑时的模板,有了模板,需要生产的时候就只管向里面注入具体的材料就行,不同的材料可以产生不同的效果,这便是泛型最初的设计宗旨。

  • 泛型将代码安全性检查提前到编译期。

泛型被加入 Java 语法中,还有一个最大的原因:解决容器的类型安全,使用泛型后,能让编译器在编译的时候借助传入的类型参数检查对容器的插入,获取操作是否合法,从而将运行时 ClassCastException 转移到编译时。比如:

List dogs = new ArrayList();
dogs.add(new Cat());

在没有泛型之前,这种代码除非运行,否则你永远找不到它的错误。但是加入泛型后,

List dogs = new ArrayList<>();
dogs.add(new Cat()); // Error Compile

会在编译的时候就检查出来。

  • 泛型能够省去类型强制转换。

在 JDK1.5 之前,Java 容器都是通过将类型向上转型为 Object 类型来实现的,因此在从容器中取出来的时候需要手动的强制转换。

Dog dog = (Dog)dogs.get(1);

加入泛型后,由于编译器知道了具体的类型,因此编译器会自动进行强制转换,使得代码更加优雅。

早期 Java 是使用 Object 来代表任意类型的,但是向下转型有强转的问题,这样程序就不太安全。

有了泛型以后:

  • 代码更加简洁【不用强制转换】
  • 程序更加健壮【只要编译时期没有警告,那么运行时期就不会出现 ClassCastException 异常】
  • 可读性和稳定性【在编写集合的时候,就限定了类型】
  • 使用增强 for 遍历集合

1.2 泛型的定义

自 JDK 1.5 之后,Java 通过泛型解决了容器类型安全这一问题,而几乎所有人接触泛型也是通过 Java 的容器。那么泛型究竟是什么?

泛型的本质是参数化类型。

也就是说,泛型就是将所操作的数据类型作为参数的一种语法。

public class Play {
    T play(){}
}

其中 T 就是作为一个类型参数在 Play 被实例化的时候所传递来的参数,比如:

Play playInteger = new Play<>();

这里 T 就会被实例化为 Integer。

Java 泛型设计原则:只要在编译时期没有出现警告,那么运行时期就不会出现 ClassCastException 异常。

泛型:把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型。

参数化类型:

  • 把类型当作是参数一样传递
  • <数据类型>只能是引用类型

相关术语:

  • ArrayList 中的 E 称为类型参数变量
  • ArrayList 中的 Integer 称为实际类型参数
  • 整个 ArrayList 称为泛型类型
  • 整个 ArrayList 称为参数化的类型

1.3 泛型擦除

泛型是提供给 java 编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛型的 java 程序后,生成的 class 文件中将不再带有泛型信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。

泛型是类型擦除的,参考:点击这里

你可能感兴趣的:(架构师筑基必备技能,java)