目录
1.什么是泛型
泛型(Generics)允许在定义类、接口和方法时使用类型参数,以便在代码编写时指定实际的数据类型。(简单来说,就是我们可以通过指定当前的容器要持有什么类型的对象,让编译器去检查)
1.1什么是装箱,拆箱
装箱:指将基本数据类型装换成对应的包装类型(比如:将int 转换成 Integer).
拆箱:指将包装类型转换成对应的基本数据类型(比如:将 Double 装换成 double).
int a = 100;
Integer b = a; // 自动装箱,将int类型转为Integer类型
int c = b; // 自动拆箱,将Integer类型转为int类型
1.2泛型的作用
class MyArry{
public Object[] array = new Object[100];
public Object getPos(int pos) {
return this.array[pos];
}
public void setVal(int pos,Object val) {
this.array[pos] = val;
}
}
public class Test {
public static void main(String[] args) {
MyArry myArry = new MyArry();
myArry.setVal(1,2);
myArry.setVal(2,"你好");
String ret = myArry.getPos(2);//编译报错
System.out.println(ret);
}
}
以上代码出现的问题:
1. 任何类型数据都可以存放2. 1 号下标本身就是字符串,但是确编译报错。必须进行强制类型转换
1.3如何使用泛型
class 泛型类名称 < 类型形参列表 > {// 这里可以使用类型参数}class ClassName < T1 , T2 , ..., Tn > {}
//class MyArry{
// public Object[] array = new Object[100];
// public Object getPos(int pos) {
// return this.array[pos];
// }
// public void setVal(int pos,Object val) {
// this.array[pos] = val;
// }
//}
class MyArry<T>{
public T[] array =(T[]) new Object[100];
public Object getPos(int pos) {
return this.array[pos];
}
public void setVal(int pos,T val) {
this.array[pos] = val;
}
}
public class Test {
public static void main(String[] args) {
// MyArry myArry = new MyArry();
// myArry.setVal(1,2);
// myArry.setVal(2,"你好");
// String ret = myArry.getPos(2);//编译报错
// System.out.println(ret);
MyArry<Integer> myArry = new MyArry<>();
myArry.setVal(1,2);
myArry.setVal(2,"你好");//此处编译器直接提醒我们添加的数据类型错误
String ret = myArry.getPos(2);//编译报错
System.out.println(ret);
}
}
代码:
//class MyArry{
// public Object[] array = new Object[100];
// public Object getPos(int pos) {
// return this.array[pos];
// }
// public void setVal(int pos,Object val) {
// this.array[pos] = val;
// }
//}
class MyArry<T>{
public T[] array =(T[]) new Object[100];
public Object getPos(int pos) {
return this.array[pos];
}
public void setVal(int pos,T val) {
this.array[pos] = val;
}
}
public class Test {
public static void main(String[] args) {
// MyArry myArry = new MyArry();
// myArry.setVal(1,2);
// myArry.setVal(2,"你好");
// String ret = myArry.getPos(2);//编译报错
// System.out.println(ret);
MyArry<Integer> myArry = new MyArry<>();
myArry.setVal(1,2);
myArry.setVal(2,"你好");//此处编译器直接提醒我们添加的数据类型错误
String ret = myArry.getPos(2);//编译报错
System.out.println(ret);
}
}
2.泛型是如何编译的
2.1擦除机制
在编译的过程中,将泛型信息去掉,同时将类型参数转换成限定的类型或者Object,比如将MyArray<String>擦除为MyArray<Object>.
解析:为什么需要擦除机制?为了保持与老版本java代码的兼容性,因为泛型这个概念是在java5的时候才引进的,为了兼容5以前的代码,所以擦除机制应运而生.
2.2插入类型转换
确保类型的兼容和安全,在插入元素时检查插入的类型和类型的转换,比如:在插入MyArray<Object>时我们会检查插入的数据是不是Object类型的,同时还有保障插入的数据为String类型的.
总结:
泛型优点:
1.使用泛型可以保障java程序的类型安全
2.可以在编译时即早的发现错误
3.代码重用和可读性,泛型可以使用同一段代码在不同的的数据类型上工作,提高了代码的复用性.