泛型,又名"参数化类型",顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
已经有基本数据类型了,还引入泛型,为什么呢?
举个例子:
未使用泛型:
class printArr{
public void Parr(char[] Arr){ //字符串类型
for (int i = 0; i<Arr.length;i++){
System.out.print(Arr[i]);
}
System.out.println();
}
public void IArr(int[] Iarr ){ //int类型
for (int i = 0; i<Iarr.length;i++){
System.out.print(Iarr[i]);
}
}
}
public class lizi {
public static void main(String[] args) {
char[] Arr = {'H', 'E', 'L', 'L', 'O'};
int[] Iarr = {1,2,3,4,5,6,7};
printArr pa = new printArr();
pa.Parr(Arr);
pa.IArr(Iarr);
}
}
运行结果:
1 HELLO
2 1234567
由上的代码我们看见有许多冗余代码,作为一个优秀的程序员,我们肯定会用少量的代码,实现不变的功能,我们想到了用数据通用对象Object,说来就来,干了这段代码。。。一分钟后,我又回来了。Perfect,可以使用。
class printArr{
public void Parr(Object[] Arr){ //字符串类型
for (int i = 0; i<Arr.length;i++){
System.out.print(Arr[i]);
}
System.out.println();
}
}
public class lizi {
public static void main(String[] args) {
Object[] Arr = {'H', 'E', 'L', 'L', 'O'};
Object[] Iarr = {1,2,3,4,5,6,7};
printArr pa = new printArr();
pa.Parr(Arr);
pa.Parr(Iarr);
}
}
运行结果:
1 HELLO
2 1234567
3
4 Process finished with exit code 0
But,虽然这段代码看起来,非常灵活,可以接收任何数据类型,可以说是一劳永逸。但全面地讲,也不是没有缺陷的,主要表现在:当代码处理值类型时,会出现装箱、拆箱操作,但将用到的数据类型的强制转换操作,增加处理器的负担。
So,我们想到,能不能用一种方法,当我们调用方法时自动分配数据类型,不用再重复的封箱,拆箱,Congratulations,我们发现了泛型,,用一个通用的数据类型T来作为一个占位符,等待在实例化时用一个实际的类型来代替。let our see see 泛型的霸道之处。
我又来了,总算是好了。代码如下
class printArr{
// 泛型方法 printArray
public < E > void printArray( E[] inputArray )
{
// 输出数组元素
for ( E element : inputArray ){
System.out.printf( "%s", element );
}
System.out.println();
}
}
public class lizi {
public static void main(String[] args) {
Character[] Carr = {'H', 'E', 'L', 'L', 'O'};
Integer[] Iarr = {1,2,3,4,5,6,7};
printArr pa = new printArr();
pa.printArray(Carr);
pa.printArray(Iarr);
}
}
运行结果:
1 HELLO
2 1234567