通俗易懂谈泛型(1)

  • 泛型非常有用,笑言之:『泛泛而谈』的类型,意思就是这个类型是一个不确定的类型,只有具体实现的时候才确定是什么类型。
  • 有一种东西,可以是很多种类型都通用的,但只有使用的时候才确定这个到底是什么具体的类型。
  • 举个例子:比如你有一个盒子,里面可以放任意不易碎的东西,那这个东西不确定,就可以先定义成『泛泛而谈』的类型,这时就可以计算盒子里有多少个东西,添加,减少东西的方法。
  • 当然,最典型的例子就是各种集合类,你可以在各种集合里放任意类型,比如:ArrayList
  • 这里你可能想:『那我就放入一个Object,到使用时强制类型转换过来,不就得了吗?为什么非要用泛型呢?没必要啊。』少侠莫慌,往下看它的两个优点就知道了,且听我慢慢道来…

为什么要用泛型

意味着少侠你写的代码可以被很多不同类型的对象所重用–》读到这里你是不是就明白了:这就是抽象

使用泛型的好处

  1. 解决多类型的强制类型转换–》很多不同类型对象可以重用,而不是强转,因为强转是不安全的。
  2. 不需要错误检查,更加可读和安全

定义

泛型类(generic class):具有一个或多个类型变量的类

重要的通配符类型

1
<T> // 里面可以是任意大写字符 这个就表示任意类型、简单明了吧

如何使用它?

  • 泛型类

1
2
3
4
5
6
// 可以任意个类型
public TestClass<T>{}
public TestClass<T, U>{}
public TestClass<T, U, W>{}
使用规则
  1. 尖括号括起来
  2. 放在类名的后面

以上是泛型类

  • 泛型方法

1
2
3
4
5
public static <T> T getValue(T[] keys){
// 这是一个返回类型为T
// 参数是T的数组
// 的泛型方法
}
使用规则
  1. 放在方法修饰符(public static)后面
  2. 放在方法返回值前面
  3. 也叫类型变量

类型变量的限定

说直白点就是,类型变量也是可以有条件的,就好比你去买书,历史类的书,这个就是条件。

1
2
3
4
// 一个时
public static <T extends Comparable> T min(T[] a)...
// 多个时
public static <T extends Comparable & Serializable> T min(T[] a)...

泛型代码编译时是怎样运行的

  1. 泛型代码最终还是编译时还是运行在虚拟机上的
  2. 虚拟机上没有泛型类型对象、只有普通的类和方法
  3. 所有的泛型类型会被替代为与其对应的原始类型(raw type)
  4. 的原始类型是Object
  5. 的原始类型是Comparable(就近原则)
  6. 将没有方法的接口放在列表的末尾可以提高效率(因为编译器必要时需要插入强制类型转换)

泛型表达式以及泛型方法的翻译

当程序调用涉及到泛型时

  1. 翻译成原始类型
  2. 必要时自动强制类型转换
  3. 上面提到的就近原则会千万方法的插除,这个会带来多态以及方法覆盖的问题–》合成的桥方法

泛型的局限性(不能做什么)

不能用基本类型实例化参数

  1. 比如: 没有ArrayList 只有ArrayList 原因:类型擦除时带来的 Object不能存储double
  2. 可以使用8种基本类型以及自定义的类

运行时类型查询 只适用于原始类型

通配符类型

1
2
3
4
5
6
// 通配符类型
TestClass<? extends Thread>
// 通配符的超类型限定
TestClass<? super Thread>
// 无限定通配符 但不能在代码中使用?作为一种类型
TestClass<?>

通配符类型不是一种类型变量

任康可 wechat
欢迎您扫一扫上面的二维码,订阅我的微信公众号!
坚持原创技术分享,您的支持将鼓励我继续创作!