1.包装类的概念:
将 基本类型(int char ) 封装成对象的类。在java中包装类包括Integer Character Double等。
装箱和拆箱:
装箱:将 基本类型 转换位 包装类对象,如:将int转化为Integer
拆箱:与装箱相反,将 包装类对象 转化为 基本类型 :Integer转化为int
EX1:
// 装箱
int num = 42;
Integer boxedNum = Integer.valueOf(num); // 或 Integer boxedNum = num; (自动装箱)
// 拆箱
int unboxedNum = boxedNum; // 自动拆箱
int primitiveNum = unboxedNum.intValue(); // 或 int primitiveNum = unboxedNum; (自动拆箱)
这里 将num转化为Integer类型并将其赋给boxedNum存储起来
2.泛型的概念:编程中一种允许在类、接口和方法中使用类型参数的特性,使得代码更具
通用性和类型安全。简单来说就是
适用于多种类型,
使用泛型可以避免强制类型转换,提高代码的重用性。
(主要目的:
就是指定当前的容器,要持有什么类型的对象。让编译
器去做检查).
2.2泛型的语法:
class 泛型类名称<类型形参列表> {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> {
}
class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {
// 可以只使用部分类型参数
}
EX1:
实现一个类,类中包含一个数组成员,使得数组中可以存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值.
class MyArray<T> { //设置MyArray类
public Object[] array = new Object[10]; //创建一个容量为10的、容纳Object类的数组
public T setVal(int pos,T val) //设置get、 set方法
{
array[pos] = val;
return (T)array[pos];
//or
/*
if(pos>=0 && pos<array.length)
{
array[pos] = val;
}else{
throw new IndexOutOfBoundsException("Index Out Of Bounds"+pos);
}
*/
}
public T getPos(int pos)
{
//if(pos>=0&&pos<array.length)
//{ return ~};
return (T) array[pos];
}
}
public class Test {
public static void main(String[] args) {
MyArray<Integer> myArray = new MyArray<>();//使用泛型创建一个myArray对象,泛型参数为Integer
myArray.setVal(0,1); //设置对应的值
myArray.setVal(1,1234);
int ret = myArray.getPos(1); //通过ret ret2 接受值
int ret2 = myArray.getPos(0);
System.out.println(ret);
System.out.println(ret2);
MyArray<String> myArray1 = new MyArray<>(); //通过泛型创建一个泛型参数为String的myArray1对象
myArray1.setVal(0,"King");
String s1 = myArray1.getPos(0);
System.out.println(s1);
}
}
这里为什么要用Object类去创建数组array呢?因为java不允许直接创建泛型类型的数组,
-
类型擦除:Java 泛型在运行时会被擦除,这意味着在运行时泛型的具体类型信息不可用。这使得直接创建泛型数组变得复杂或不可行。
-
类型安全:即使可以创建泛型数组,Java 也会遇到类型安全问题。因为泛型数组在运行时不具备类型检查,这可能导致
ClassCastException
。
2.3泛型编译过程中的擦除机制:
在编译的过程当中,将所有的
T
替换为
Object
这种机制,我们称为:
擦除机制
。
2.4泛型的上界:
在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束。
基本语法:
class 泛型类名称<类型形参 extends 类型边界> {
...
}
EX1:
public class Test{
public static <T extends Number> void printNumber(T number) {
System.out.println(number);
}
public static void main(String[] args) {
printNumber(123);
printNumber(123.123);
//printNumber("String");//不在Number范围里
}
}
//<T extends Number>
是一种泛型边界的使用方式,它限制了泛型类型 T 的范围,使其只能是 Number
的子类(如 Integer
, Double
, Float
等)。这种边界可以确保在处理数据时类型的一致性和安全性。
泛型方法:
方法限定符
<
类型形参列表
>
返回值类型
方法名称
(
形参列表
) { ... }
EX1:
public class GenericExample{
//泛型方法:
public <T> void printArray(T[] array){
for (T elements:
array) {
System.out.println(elements); //增强for循环遍历
}
}
}
GenericExample genericExample = new GenericExample();
//用泛型方法打印 Integer数组
Integer[] intArray = {1,2,3,4,5};
genericExample.printArray(intArray);
//用泛型方法打印 String数组
String[] stringsArray = {"hello","world"};
genericExample.printArray(stringsArray);
//利用printArray方法可以处理各种类型的数组
这就是今天要介绍的内容了,喜欢的老铁们来个关注再走吧!