起源
泛型编程是一种编程风格,其中算法以尽可能抽象的方式编写,而不依赖于将在其上执行这些算法的数据形式。这个概念在年首次由DavidMusser和AlexanderA.Stepanov提出[1.参考]。
年,AlexanderA.Stepanov和他的同事DenielE.Rose出版的FromMathematicstoGenericProgramming一书中文版已出版对泛型编程进行更为精确的定义。
泛型编程是一种专注于对算法及其数据结构进行设计的编程方式,它使得这些算法即数据结构能够在不损失效率的前提下,运用到最为通用的环境中。
泛型编程的提出者
泛型这个词并不是通用的,在不同的语言实现中,具有不同的命名。在Java/Kotlin/C#中称为泛型(Generics),在ML/Scala/Haskell中称为ParametricPolymorphism,而在C++中被叫做模板(Template),比如最负盛名的C++中的STL。任何编程方法的发展一定是有其目的,泛型也不例外。泛型的主要目的是加强类型安全和减少强制转换的次数。
Java中的泛型编程
在Java中有泛型类和泛型方法之分,这些都是表现形式的改变,实质还是将算法尽可能地抽象化,不依赖具体的类型。
genericsaddawaytospecifyconcretetypestogeneralpurposesclassesandmethodsthatoperatedonObjectbefore
通用的类和方法,具有代表性的就是集合类。在Java1.5之前,Java中的泛型都是通过单根继承的方式实现的。比如:
publicclassArrayList//beforeJavaSE5.0{publicObjectget(inti)publicvoidadd(Objecto)publicbooleancontains(Objecto);privateObject[]elementData;}
虽然算法足够通用了,但是这样会带来两个问题。一个是类型不安全,还有一个是每次使用时都得强制转化。减少类型转换次数比较容易理解,在没有泛型(参数化类型)的时候,装进容器的数据,其类型信息丢失了,所以取出来的时候需要进行类型转换。例如:
Listlist=newArrayList();list.add(1);assertThat(list.get(0),instanceOf(Integer.TYPE));assertThat((Integer)list.get(0),is(1));//存在强制转换
因为这个类里只有Object的声明,所以任意类型的对象都可以加入到这个集合当中,在使用过程中就会存在强制到具体的类型失败的问题,这将丧失编译器检查的好处。
Listlist=newArrayList();list.add(1);list.add("anytype");assertThat(list.get(1),instanceOf(String.class));assertThat((Integer)list.get(1),is(1));//-java.lang.ClassCastException:java.lang.Stringcannotbecasttojava.lang.Integer
JavaSE5引入了泛型,不仅有效地提高了算法的通用程度,同时也保留强类型语言在编译期检查的好处。
GenericsThislong-awaitedenhancementtothetypesystemallowsatypeormethodtooperateonobjectsofvarioustypeswhileproviding