【Java】—— 包装类泛型
一、包装类(Wrapper Class)
1、包装类的定义
在Java中数据分为两大类:
- 基础数据类型(内置数据类型)
- 引用类型
其中基础数据类型(byte int long double boolean char......)和C语言接近是早期为了吸引C语言的程序员。后续 Java 有引入了一系列更进阶的语法机制,而这些机制又依赖于引用类型。
Java 希望把所有的类型统一成 Object 体系,让基础数据类型也可以使用 equals , clone 等方法。 于是在标准库中创建了一组类,将内置类型的变量包装一下,就有了包装类
只要在包装类中创建一个基础数据类型的成员,就可以在实现基础数据类型的同时,使用其他对象的方法
2、包装类的名称
8个基本数据类型分别提供了8个包装类分别对应
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
除了 Integer 和 Character 其余基本类型的包装类都是首字母大写
3、装箱和拆箱
包装类虽然是类,但是在进行算术运算时还是需要转成内置类型再进行运算
内置类型 -> 包装类 的过程称为 装箱
包装类 -> 内置类型 的过程称为 拆箱
从 Java8 开始就有了自动装箱和自动拆箱的功能
二、泛型(Generics)
1、泛型的定义
是一种在软件开发中使用的一种技术,允许在定义类、接口和方法时使用一个或多个类型作为参数。
学习数组时我们知道,一个数组中只能存放一种数据类型
class MyArray{
public int[] array = new int[10];
public int get(int index){
return this.array[index];
}
public void set(int index,int value){
array[index] = value;
}
}
当我们实例化数组时只能使用 int 这个类型,如果我们需要使用其他类型时就需要再复制这段代码并修改数据类型。
我们可以通过将这段代码中的 int 类型换成泛型,让实例化时再决定数据类型,这样既可以是 int 也可以是 char,这样就提升了代码的复用率。
2、语法
class 泛型类名称<类型形参列表>{
....
}
class classname<T1,T2,...,Tn>{
....
}
类名后的方括号 <> 代表占位符,表示当前类是一个泛型类
类型形参一般使用一个大写字母来表示,常用的有
- E : Element
- K : Key
- V : Value
- N : Number
- T : Type
- S、U、V 等等: 第二、第三、第四个类型
泛型的实例化:
泛型类<类型实参> 变量名 = new 泛型类<类型实参>(构造⽅法实参)
将前文说到的数组进行修改
class MyArrayTemplate <T>{
private T[] array = (T[]) new Object[10];
public T get(int index){
return array[index];
}
public void set(int index,T value){
//输入的数据类型是T类型,所以形参这也要写成T
array[index] = value;
}
}
public class text1 {
public static void main(String[] args) {
MyArrayTemplate<Integer> arr1 = new MyArrayTemplate<Integer>();
MyArrayTemplate<String> arr2 = new MyArrayTemplate<String>();
//针对泛型参数来说,只能指定引用类型,不能指定内置类型
//泛型这一套语法体系,底层还是靠 Object 这一系列的继承关系来完成的
}
}
3、裸类型(Raw type)
裸类型是一个泛型类但是没有带着类型实参
MyArrayTemplate<> arr1 = new MyArrayTemplate<>();
不要主动去使用裸类型,这个语法是为了兼容老版本的 API 保留的机制
4、类型擦除
编译器在对泛型进行编译时会直接将 <T> 当做 Object 进行处理,只不过会在后面加上一系列类型检查,实例化时就会将 类型 与 Object 类型互相转换
5、泛型的上界
利用 Java 继承的特性来对泛型类的参数进行限制
语法:
class 泛型类名称<类型形参 extends 类型边界>{
.....
}
6、泛型通配符
? 用于在泛型的使用就称做通配符
当类型被指定为 Integer 后就不能再被指定为 String ,如果我们需要接收所有的泛型类型,又不能够让用户随意修改就需要使用通配符来处理,代码如下:
public class text2 <t>{
public static void main(String[] args) {
text2<?> t = new text2<Integer>();
t = new text2<String>();
}
}