[ 数据结构 ] 泛型 (上)
目录
一. 包装类
1.基本数据类型对应的 包装类
包装类的主要用途
2. 装箱和拆箱
①装箱操作 :
②拆箱操作 :
③自动装箱与拆箱 :
④缓存机制 :
二. 泛型
1.语法
三 .泛型类的使用
1.语法
2.类型推导
四.泛型的使用
1.擦除机制
2.泛型的通配符
3 泛型方法
①语法
②示例 (swap)
完
一. 包装类
在Java中 , 由于基本类型不是继承自Object , 为了在泛型代码中可以支持基本类型 , Java给每个基本类型都对应了一个包装类型
1.基本数据类型对应的 包装类
基本数据类型 | 包装类 |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
包装类的主要用途
- 将基本数据类型转换为对象 包装类允许基本数据类型以对象的形式存在 , 便于在集合(如ArrayList , HashMap)中是使用
- 提供实用方法 包装类提供了许多实用方法 例如
Integer.parseInt()
、Double.toString()
等 - 支持自动装箱与拆箱 Java5 引入了自动装箱和自动拆箱的功能 , 简化了基本数据类型与包装类之间的切换
2. 装箱和拆箱
①装箱操作 :
- 将 基本类型对象 转换为 包专类型对象
- 例如 : 创建一个Interger类型对象 , 将 i 的值放入对象的某个属性当中
②拆箱操作 :
- 将 包装类型对象 转换为 基本类型对象
- 例如 : 将Interger 对象中的值取出 , 放到一个基本数据类型中
③自动装箱与拆箱 :
Java 5 引入了 自动装箱 和 拆箱 功能,简化了基本数据类型与包装类之间的转换。
public static void main(String[] args) {int i = 10;//装箱操作Integer ii = Integer.valueOf(i);//显式装箱Integer io = new Integer(i);//显式装箱Integer ia = 12;//自动装箱Integer is = i;//自动装箱Integer ib = (Integer) i;//自动装箱//拆箱操作int jv = ii.intValue();//显式拆箱int ja = ii;//自动拆箱int js = (int)ii;//自动拆箱}
④缓存机制 :
Integer
、Short
、Byte
、Character
和Long
在-128到127之间有缓存,直接使用 ==
比较可能返回true
即对象若在 -128到127 之间 , 则第二次使用就会有缓存 , 不用 new 新的对象
public static void main(String[] args) {Integer a = 127;Integer b = 127;Integer c = 128;Integer d = 128;System.out.println(a.equals(b));//trueSystem.out.println(c.equals(d));//trueSystem.out.println(a == b);//true(-128到127之间有缓存)System.out.println(c == d);//false}
二. 泛型
泛型是Java中引入的一种类型参数化机制,允许在类、接口或方法中使用类型参数
简单来说 : 泛型 :就是 适用于许多类型 .
从代码上讲 , 就是对类型是是实现了参数化
泛型的主要目的 : 指定当前的容器, 要持有什么类型的对象
1.语法
class 泛型类名称<类型形参列表> {// 这里可以使用类型参数
}class ClassName<T1, T2, ..., Tn> {
}
class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {// 这里可以使用类型参数
}class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {// 可以只使用部分类型参数
}
例子 : 实现一个类 , 类中包含一个数组成员 , 使得数组中可以存放任何类型的数据
import java.util.Arrays;//实现一个类 , 类中包含一个数组成员 , 使得数组中可以存放任何类型的数据
class MyArray<T>{public Object[] array = new Object[10];public T getArray(int pos) {return (T)this.array[pos];}public void setArray(T val,int pos) {this.array[pos] = val;}@Overridepublic String toString() {return Arrays.toString(array) ;}
}
public static void main(String[] args) {MyArray<Integer> myArray1 = new MyArray<Integer>();myArray1.setArray(10,0);myArray1.setArray(12,1);//myArray1.setArray("aa",2);//自动类型检查Integer ret = myArray1.getArray(0);System.out.println(myArray1);MyArray<String> str = new MyArray<String>();str.setArray("shs",3);System.out.println(str);}
代码注释:
①类名后的 <T> 代表占位符 , 表示当前类是一个泛型类
② 类型后加入 <Integer> 等 , 用来指定当前类型
③代码编译报错 , 此时因为 当前指定类型为 <Integer> ,在此处存放元素时会帮助我们进行类型检查
三 .泛型类的使用
- 泛型类是使用泛型特性定义的类,即在类声明中引入了类型参数
- 泛型类是泛型的一种具体应用形式
1.语法
泛型类<类型实参> 变量名; // 定义一个泛型类引用
new 泛型类<类型实参>(构造方法实参); // 实例化一个泛型类对象
MyArray<Integer> list = new MyArray<Integer>();
注意 : 泛型只能接受类 , 所有的基本数据类型必须使用包装类
2.类型推导
当便以其可以根据上下文推导出类型实参时 , 可以省略类型实参的填写
MyArray<Integer> list = new MyArray<>(); // 可以推导出实例化需要的类型实参为 Integer
四.泛型的使用
1.擦除机制
- 在编译过程中 , 将所有 T 替换为 Object 这种机制,称为 : 擦除机制
- Java的泛型是通过类型擦除实现的,即在编译后泛型类型信息会被擦除,替换为原始类型(如
Object
)或边界类型。例如,Box<String>
在运行时会被擦除为Box
Box<String> stringBox = new Box<>();
Box<Integer> integerBox = new Box<>();
// 编译后,两者的类类型相同,均为Box
Java的泛型机制是在编译级别实现的 , 编译器生成的字节码在运行期间并不包含泛型的类型信息
2.泛型的通配符
泛型通配符 ?
用于表示未知类型,通常用于方法参数或变量声明中
<?>
:无界通配符,表示任何类型。<? extends T>
:上界通配符,表示T
或其子类。<? super T>
:下界通配符,表示T
或其父类。
3 泛型方法
①语法
方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { ... }
②示例 (swap)
//静态的泛型方法 需要在static后用 <> 声明泛型类型参数public static <E> void swap(E[] array,int i,int j){E t = array[i];array[i] = array[j];array[j] = t;}