简述泛型

发布于 2021-11-16  2240 次阅读


1.什么是泛型

JDK 1.5 中出现,泛型的本质是参数化类型,把所操作的数据类型被指定为一个参数“参数化类型”

2.为什么要用泛型

1.不用泛型(有程序)

每次使用时都需要强制转换成想要的类型

在编译时编译器并不知道类型转换是否正常,运行时才知道,不安全,所以不推荐使用原生态类型!!

(有程序)

2.泛型特点

类型安全

  • 泛型的主要目标是提高 Java 程序的类型安全
  • 编译时期就可以检查出因 Java 类型不正确导致的 ClassCastException 异常
  • 符合越早出错代价越小原则

消除强制类型转换

  • 泛型的一个附带好处是,使用时直接得到目标类型,消除许多强制类型转换
  • 所得即所需,这使得代码更加可读,并且减少了出错机会
  • 所有的强制转换都是自动和隐式的,提高代码的重用率。

潜在的性能收益

  • 由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改
  • 所有工作都在编译器中完成
  • 编译器生成的代码跟不使用泛型(和强制类型转换)时所写的代码几乎一致,只是更能确保类型安全而已

不能是基本类型

3.泛型类型擦除

1.Java 的泛型在编译器有效,在运行期被删除

所有泛型参数类型在编译后都会被清除掉

JVM并不知道泛型的存在,因为泛型在编译阶段就已经被处理成普通的类和方法; 处理机制是通过类型擦除,擦除规则:

若泛型类型没有指定具体类型,用Object作为原始类型; 若有限定类型< T exnteds X_Class >,使用X_Class作为原始类型; 若有多个限定< T exnteds X_Class1 & X_Interface >,使用第一个边界类型XClass1作为原始类型;

2.泛型类型在逻辑上可以看成是多个不同的类型,实际上都是相同的基本类型。

3.导致不能够以任何有实际意义的方式去使用泛型的类型

public< T > void performAction( final T action )

{ T[] actions = new T[0]; }

错误Cannot create a generic array of T”异常

A<String>[] arr = new A<String>[1];
Object[] objArr = arr;
objArr[0] = new A<Integer>();
把 arr 赋给一个 Object[],然后我们往数组中加入 A<Integer> 类型的值,这样做是可以的,在编译和运行期间都不会报错。因为泛型类型会被擦除,A<String> 和 A<Integer> 的类型其实是一样的:
System.out.println(new A<String>().getClass() == new A<Integer>().getClass());
// 输出:true

4.如何使用泛型(T,E,K,V)

1.泛型类

2.泛型接口

3.泛型方法

1.静态方法上的泛型:

静态方法无法访问类上定义的泛型。如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上。

1.泛型定义在方法上原因

因为泛型是要在对象创建的时候才知道是什么类型的,而对象创建的代码执行先后顺序是static的部分,然后才是构造函数等等。所以在对象初始化之前static的部分已经执行了,如果你在静态部分引用的泛型,那么毫无疑问虚拟机根本不知道是什么东西,因为这个时候类还没有初始化。因此在静态方法、数据域或初始化语句中,为了类而引用泛型类型参数是非法的


星星温柔泛滥,人间至善