从学习C#的时候就开始接触泛型,直到学习JAVA后对泛型的理解依然只停留在表面。最开始接触泛型时,是为了方便类型转换和保证类型安全,至于泛型的原理则了解的很少
最初对泛型的概念是“指定具体类型”,但这种认识好像与“泛”的意思正好相反,“泛”的意思应该是“抽象”或者“模板”等等。
这次在做一个DRP的项目时,凡涉及到Collection的地方都使用了泛型,而且接触到了泛型类。于是决定深入了解一下泛型。
先来看下java.util.List接口的声明
public interface List<E> extends Collection<E> {
int size();
.....
boolean add(E e);
E get(int index);
.........
}
我们会发现它用E来代替具体的类型,这样就实现了将类型参数化,具体E代表什么类型,由使用时决定
List<Integer> list;
在这里E具体就是Integer
于是我们发现了其实泛型设计就是将类型进行抽象,提炼出一个模板,这个模板可以接受任何类型的实例化,大框架是给定了,具体的类型由具体使用时指定,这样就增加了编程的灵活性。
例如一个Math类有一个比较两个数是否相等的函数IsEqual()
如果不使用泛型,需要写多个重载
public class Math{
//比较整型变量
public boolean IsEqual(int first,int second);{
boolean flag;
if(first==second){
flag=true;
}else{
flag=false;
}
return flag;
}
//比较单精度变量
public boolean IsEqual(float first,float second);{
boolean flag;
if(first==second){
flag=true;
}else{
flag=false;
}
}
//.....比较其他类型的数值变量
}
但是如果使用泛型,那就好办了,只需写一个函数
public class Math<T>{
public boolean IsEqual(T first,Tsecond);{
boolean flag;
if(first==second){
flag=true;
}else{
flag=false;
}
return flag;
}
}
具体使用时,这样写即可
Math<Integer> math=new Math<Integer>();
boolean result=math.IsEqual(5,6);
使用时指定具体类型
学过C++的同学知道,C++中有模板类和模板方法,其实他们也是对泛型的一种实现
于是我们可以得出下面的结论:
通过泛型提炼出模板
具体类型由使用时决定
通过指定具体类型可以限定类型的范围,从而将错误的检查提前到编译期间
指定了具体类型也就去除了转型的繁琐和失误
这是我对泛型的一点小认识。