目录
- 泛型类的使用
- 泛型类如何编译的
- 泛型类的上界
- 泛型方法
- 通配符上界
- 通配符下界
一、包装类
在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型。
基本数据类型和对应的包装类
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
二、装箱和拆箱
概念:
装箱操作: 新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中
拆箱操作: 将 Integer 对象中的值取出,放到一个基本数据类型中
eg:

自动装箱和自动拆箱

三、什么是泛型
通俗讲:就是适用于许多许多类型
泛型的主要目的:
就是指定当前的容器,要持有什么类型的对象。让编译器去做检查。此时,就需要把类型,作为参数传递。需要什么类型,就传入什么类型。
语法:
class 泛型类名称<类型形参列表> {
}
// 其他写法:
class 泛型类名称<类型形参列表> extends 继承类 {
}
eg:
Class ClassNane<T> {
}
类名后的 T 代表占位符,表示当前类是一个泛型类
了解:
【规范】类型形参一般使用一个大写字母表示,常用的名称有:
- E 表示 Element
- K 表示 Key
- V 表示 Value
- N 表示 Number
- T 表示 Type
- S, U, V 等等 – 第二、第三、第四个类型
泛型类的使用
语法:
泛型类<类型实参> 变量名 = new 泛型类<类型实参>(构造方法实参);
注意:泛型只能接受类,所有的基本数据类型必须使用包装类!
当编译器可以根据上下文推导出类型实参时,可以省略类型实参的填写
eg:
MyArray<Integer> list = new MyArray<>();
小结:
(I)泛型是将数据类型参数化,进行传递
(II)使用 表示当前类是一个泛型类。
(III)泛型目前为止的优点:数据类型参数化,编译时自动进行类型检查和转换
泛型如何编译的
(I)基本概念:
- 在编译时,Java 编译器会将泛型类型信息从代码中移除,这个过程就叫做类型擦除。
- 擦除后,泛型类型会被替换为其边界类型(通常是Object)或者指定的类型。
(II)擦除过程:
- 将泛型参数替换为其边界或 Object。
- 在必要的地方插入类型转换以保持类型安全。
- 生成桥接方法以保持多态性
- 泛型类型擦除可能导致子类方法和父类方法的签名不一致。
- 为了维护 Java 的多态性,需要桥接方法来确保子类方法能够正确覆盖父类方法。
- 编译器会自动生成一个桥接方法
泛型的上界
语法:
class 泛型类名称<T(类型形参) extends 类型边界> {
}
// T 要么是Number的子类;要么是Number这个类自己
泛型方法
语法:
方法限定符 <类型形参列表> 返回值类型 方法名称 {
…
}
//静态的泛型方法 需要在static后用<>声明泛型类型参数
使用示例:
(1)使用类型推导
(2)不使用类型推导
eg:

通配符
? 用于在泛型的使用,即为通配符
在" ? "的基础上又产生了两个子通配符:
? extends 类:设置通配符上限
? super 类:设置通配符下限
通配符上界
<? extends 上界>
eg:
<? extends Number>//可以传入的实参类型是Number或者Number的子类
通配符下界
语法:
<? super 下界>
<? super Integer>//代表 可以传入的实参的类型是Integer或者Integer的父类类型

