学习java5新特性有段时间了,关于泛型与多态的关系一直有些疑问,今天看资料时又碰到了泛型,谈谈我的新理解。
先看看什么叫泛型:
Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters. 注1
从中我们可以看出泛型的一些特征:
1. 特定的算法。这个算法逻辑对某些特定的类型都是适用的。
2. 特定的一些类型, 它们均适用1中的算法。
3. 在实现1中算法时是用抽象的符号代表2中某个特定的类型。之后使用该算法时,再用具体的类型取代这个抽象的符号。
我们知道,java中有静态(编译期)多态和动态(运行时)多态,前者通过重载实现,后者通过继承实现。我的疑问主要关注点即静态多态(重载)和泛型的关系,即有什么区别和联系,泛型是否可以取代重载,有什么细节需要注意。
先看个小例子:
public class Test{
public static void main(String[] args) {
//use generics
UseGenerics.doThing("string");
UseGenerics.doThing(new Integer(1));
UseGenerics.doThing(new UseGenerics());
//unUse generics
UnUseGenerics.doThing(new Integer(1));
UnUseGenerics.doThing(new String("string"));
}
}
class UseGenerics{
static
//do some thing
System.out.println(x.toString());
}
}
class UnUseGenerics{
static void doThing(String s){
//do some thing
System.out.println(s.toString());
}
static void doThing(Integer i){
//do some thing
System.out.println(i.toString());
}
//... other kind of doThing
}
大家注意到,UseGenerics和UnUseGenerics类分别用泛型和重载做”同样”的事情,即doThing().注意我的同样打了引号。
1. 上述的代码中,doThing实际只做了一件事,即打印传入的对象信息。这个”算法”很简单,满足泛型的特征1,对这种情况,泛型可以几乎完美的取代重载。
这里不能不提到的就是容器,我们知道容器的主要任务就是持有特定对象的引用,这个算法对于几乎所有类都是适用的,所以容器和泛型,几乎是水到渠成。泛型对容器的加强,也是最令人称道的java泛型应用。
2. 如果对doThing稍做修改,加入一些额外的代码,比如“加”这个逻辑。
对于重载而言:
2.1. doThing(String s)这个重载版本,实现String的相加,简单。
2.2. doThing(Integer i)这个重载版本,实现Integer的相加,也简单。
那关于泛型呢:
2.3.
几乎是不可完成的任务。这个“加“的算法对不同对象而言是不同的,所以,泛型无法取代重载。
看到这里,我们可以得到结论:
泛型可以部分取代重载,且是对这种类型重载的强化。这类重载有如下特征:不同重载版本的方法中算法相同,只是参数类型不同。(似乎和泛型的定义一致。。。)
1.参见http://en.wikipedia.org/wiki/Generic_programming
feitian124原创,转载请注明出处。