


【前言】
在Java中,包装类为基本数据类型提供对象封装,实现基本类型与对象的无缝转换;泛型则通过类型参数化,实现代码的通用复用并在编译期保证类型安全。二者结合,让数据结构能灵活适配多种类型,同时兼顾安全性与开发效率,是Java实现高效、通用数据操作的核心技术组合。
文章目录:
一、包装类
1. 什么是包装类?
包装类是Java中为8种基本数据类型提供的对应的类类型。它们位于java.lang包中,主要目的是将基本类型"包装"成对象,以便解决某些特殊场景。包装类实现了基本数据类型与对象之间的转换机制。
2.基本数据类型与包装类对应表
| 基本数据类型 | 包装类 |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
3.装箱和拆箱
- 装箱:将基本类型转换为包装类的过程
- 拆箱:包装类转换为基本类型的过程
int i = 10;
Integer j = Integer.valueOf(i);//手动装箱
int m = j.intValue();//手动拆箱
- 自动装箱和自动拆箱
int a = 10;
Integer b = a;//自动装箱
Integer c = (int)a;//自动装箱
【注意】
Integer 类型(默认范围:[-128~127])
超过范围就会新建对象
这时,a=200;b=200
如果打印a==b会返回false
public static void main(String[] args) {
Integer a = 180;
Integer b = 180;
System.out.println(a == b);
}

二、泛型
1.什么是泛型?
泛型(Generics)是编程语言中一种强大的特性,一般的类和方法只能使用具体的类型,而泛型可以编写适用于多种数据类型的代码,而不需要为每种类型重复编写相似的代码。泛型的主要目的是提高代码的复用性、类型安全性以及代码的清晰度。
2.基本语法
class 泛型类名称<类型形参列表>{
}
class Test<T>{
}
其他写法:
class 泛型类名称<类型形参列表> extends 继承类<这里可以使用类型参数>
3.引出泛型
实现一个类,该类中有一个可以存储任何类型数据的数组,并通过方法设置数组中的值,获取数组中的内容
public class Array {
public Object[] array = new Object[10];
public Object getPos(int pos) {
return this.array[pos];
}
public void setVal(int pos,Object val) {
this.array[pos] = val;
}
}
public static void main(String[] args) {
Array myArray = new Array();
myArray.setVal(0,10);
myArray.setVal(1,"bba");
String ret = (String) myArray.getPos(0);//强制类型转换
System.out.println(ret);
}
我们创建了一个Object类型的数组,可以存储任何类型的数据,因为Object是所有类型的父类,然后通过方法设置数组内容,但获取数据类型时会报错,发生了向下转型,这时要强制类型转换才能解决。这时,使用泛型则会更加便捷一点
使用泛型代码如下:
public static void main(String[] args) {
Array myArray = new Array();
myArray.setVal(0,10);
myArray.setVal(1,"bba");//字符串也可以存放
String ret = (String) myArray.getPos(0);//编译报错
System.out.println(ret);
}
public static void main(String[] args) {
Array <String>myArray = new Array<String>();
myArray.setVal(1,"bba");
String ret = myArray.getPos(0);
System.out.println(ret);
}
< T >:就是占位符,表示当前类是一个泛型类;
类型后的< Integer >指定当前类型,后面就不需要强制类型转换
4.泛型的使用
泛型类<类型实参>变量名;//定义一个泛型类引用
new 泛型类<类型实参>(构造方法实参);//实例化一个泛型类对象
eg:
Array<Integer> list = new Array<Integer>();
后面的new< >里面的包装类可以不写,编译器会根据前面的包装类自动推导
【注意】:泛型只能接受类,所有的基本数据类型必须使用包装类
5.擦除机制
泛型是编译时期的机制,代码运行时没有泛型这个概念
擦除机制:
在编译时,Java编译器会将泛型类型信息从代码中移除,这个过程就叫做类型擦除。
擦除后,泛型类型会被替换为其边界类型(通常是Object)或者指定的类型。
在必要的地方插入类型转换来保证类型安全
生成桥接方式以保持多态性
上面的代码擦除后:
class MyArray {
public Object[] array = new Object[10];
public Object getPos(int pos) {
return this.array[pos];
}
}
public void setVal(int pos, Object val) {
this.array[pos] = val;
}
5.泛型的上界
5.1语法
class 泛型类名称<类型形参 extends 类型边界> {
...
}
eg1:
public class Array<E extends Number>{
...
}
E 要么是Number的子类,要么是Number自己
eg2:
public class MyArray<E extends Comparable<E>> {
...
}
E必须是实现了Comparable接⼝
5.2 示例
写一个泛型类,有一个方法,求T类型数组中最大值,数组没有指定类型
- T类型是引用类型不能通过><==比较
- T类型擦除成Object,没有Comparable接口,所有要限定一下,给它一个上界
public class Alg <T extends Comparable<T>>{//T类型擦除成Object,没有Conmarable接口,所有要限定一下,给它一个上界
public T findMaxVal(T[] array){
T max = array[0];
for (int i = 0; i < array.length; i++) {
if(array[i].compareTo(max)>0){//T类型是引用类型不能通过><==比较
max = array[i];
}
}
return max;
}
}
public static void main(String[] args) {
Alg<Integer> alg = new Alg<>();
Integer[] array = {5,88,9,6,56,4};
int ret = alg.findMaxVal(array);
System.out.println(ret);
}
6.泛型方法
6.1语法
⽅法限定符 <类型形参列表> 返回值类型⽅法名称(形参列表) { ...
}
6.2 示例
泛型方法可以是static ,也可以不是static
静态方法不需要实例化引用对象,可直接调用,但参数没办法传入,so:static后面写
class Alg2{
public static<T extends Comparable<T>> T findMaxVal(T[] array){
T max = array[0];
for (int i = 0; i < array.length; i++) {
if(array[i].compareTo(max)>0){//T类型是引用类型不能通过><==比较
max = array[i];
}
}
return max;
}
}
public static void main(String[] args) {
Integer[] array = {5,88,9,6,56,4};
int ret = Alg2.findMaxVal(array);
System.out.println(ret);
}
7.通配符
? ⽤于在泛型的使⽤,即为通配符,用于表示未知类型
? extends 类:设置通配符上限 ,表示类型必须是T或其子类
? super 类:设置通配符下限,表示类型必须是T或其父类
【总结】
通过以上对Java包装类和泛型的详细介绍,我们可以看到它们在Java编程中的重要性和广泛应用。掌握好这两个知识点,对于编写高效、安全、可复用的Java代码具有重要意义。


1432

被折叠的 条评论
为什么被折叠?



