从学习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++中有模板类和模板方法,其实他们也是对泛型的一种实现
于是我们可以得出下面的结论:
通过泛型提炼出模板
具体类型由使用时决定
通过指定具体类型可以限定类型的范围,从而将错误的检查提前到编译期间
指定了具体类型也就去除了转型的繁琐和失误
这是我对泛型的一点小认识。