什么是泛型?
一般的类和方法,只能使用具体的类型:要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的舒服就会很大。-----来源<<Java编程思想>>
泛型的目的?
指定当前的容器要持有什么类型的对象,让编译器去做检查。此时,就需要把类型,作为参数传递。需要什么类型,就传入什么类型。
语法
class 泛型类名称<类型参数列表>{
}
class ClassName<T1,T2,...,Tn>{
}
实例
class MyArray<T>{
public T[] array = (T[]) new Object[10];
public T getArray(int pos){
return array[pos];
}
public void setArray(int pos,T val){
array[pos]=val;
}
}
public class TestDemo {
public static void main(String[] args) {
MyArray<Integer> myArray = new MyArray<>();//自动类型推导,后尖括号可以不写类型
myArray.setArray(0,11);
myArray.setArray(1,22);
int ret = myArray.getArray(1);
System.out.println("ret= "+ret);
//myArray.setArray(3,"keyi?");
}
}
输出结果
如果设置除Integer外的类型 Idea就会报错。
泛型是如何编译的?
通过命令javap-c 查看字节码文件 发现所有的T都转变为Object
在编译过程中 把所有的T转换为Object的这种机制 我们称之为 擦除机制。
泛型的上界
在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束
class 泛型类名称<类型形参 extends 类型边界>{
}
eg: public class MyArray<E extends Number>{
} 此后只能接受Number的子类作为E的类型实参
一个案例
写出一个泛型类,找出数组中的最大值
class Alg<T extends Comparable<T>>{
public T findMaxValue(T[] array){
T max=array[0];
for (int i = 1; i < array.length; i++) {
if(array[i].compareTo(max)>0){
max=array[i];
}
}
return max;
}
}
public class Test {
public static void main(String[] args) {
Alg<Integer> alg = new Alg<>();
Integer[] array ={77,59,15,99};
int maxValue=Alg2.findMaxValue(array);
System.out.println(maxValue);
}
}
成功找到了最大值
这里通过实现了Comparable 接口 ,获得了compareTo方法。
还有通配符问题
其实就是 使用'?'来统一化泛型形参
比如一个形参为泛型的函数
public static void PrintArray(Message<?> temp){
System.out.println(temp.getMessage);
}
这里无论泛型类Message<Integer>message 或者是 Message<String>message 都可以作实参传入该函数 增加了代码的复用性