- 泛型非常有用,笑言之:『泛泛而谈』的类型,意思就是这个类型是一个不确定的类型,只有具体实现的时候才确定是什么类型。
- 有一种东西,可以是很多种类型都通用的,但只有使用的时候才确定这个到底是什么具体的类型。
- 举个例子:比如你有一个盒子,里面可以放任意
不易碎的东西
,那这个东西不确定,就可以先定义成『泛泛而谈』的类型
,这时就可以计算盒子里有多少个东西,添加,减少东西的方法。- 当然,最典型的例子就是各种集合类,你可以在各种集合里放任意类型,比如:ArrayList
- 这里你可能想:『那我就放入一个Object,到使用时强制类型转换过来,不就得了吗?为什么非要用泛型呢?没必要啊。』少侠莫慌,往下看它的两个优点就知道了,且听我慢慢道来…
为什么要用泛型
意味着少侠你写的代码可以被很多不同类型的对象所重用
–》读到这里你是不是就明白了:这就是抽象
啊
使用泛型的好处
- 解决多类型的强制类型转换–》很多不同类型对象可以重用,而不是强转,因为强转是不安全的。
- 不需要错误检查,更加可读和安全
定义
泛型类
(generic class):具有一个或多个类型变量的类
重要的通配符类型
<T> // 里面可以是任意大写字符 这个就表示任意类型、简单明了吧
如何使用它?
- #### 泛型类
// 可以任意个类型
public TestClass<T>{}
public TestClass<T, U>{}
public TestClass<T, U, W>{}
使用规则
- 尖括号括起来
- 放在类名的后面
以上是泛型类
- #### 泛型方法
public static <T> T getValue(T[] keys){
// 这是一个返回类型为T
// 参数是T的数组
// 的泛型方法
}
使用规则
- 放在方法修饰符(public static)后面
- 放在方法返回值前面
- 也叫类型变量
类型变量的限定
说直白点就是,类型变量也是可以有条件的,就好比你去买书,历史类的书,这个就是条件。
// 一个时
public static <T extends Comparable> T min(T[] a)...
// 多个时
public static <T extends Comparable & Serializable> T min(T[] a)...
泛型代码编译时是怎样运行的
- 泛型代码最终还是编译时还是运行在
虚拟机
上的 - 虚拟机上没有泛型类型对象、只有普通的类和方法
- 所有的泛型类型会被替代为与其对应的
原始类型(raw type)
- 的原始类型是Object
泛型表达式以及泛型方法的翻译
当程序调用涉及到泛型时
- 翻译成原始类型
- 必要时自动强制类型转换
- 上面提到的就近原则会千万方法的插除,这个会带来
多态
以及方法覆盖的问题–》合成的桥方法
泛型的局限性(不能做什么)
不能用基本类型实例化参数
- 比如: 没有ArrayList 只有ArrayList 原因:类型擦除时带来的 Object不能存储double
- 可以使用8种基本类型以及自定义的类
运行时类型查询 只适用于原始类型
通配符类型
// 通配符类型
TestClass<? extends Thread>
// 通配符的超类型限定
TestClass<? super Thread>
// 无限定通配符 但不能在代码中使用?作为一种类型
TestClass<?>
通配符类型不是一种类型变量