1.Java的Generics与C++的Template
由于Java的Generics设计在C++的Template之后,因此Java的Generics设计吸取Template的很多经验和教训。首先,与Template不同的是,Generics的声明是需要进行类型检查的,而Template不提供这一功能,这使得Generics的使用更加安全。另外,Java的Generics程序只需要编译一次,以后所有程序就可以复用这个类字节码,而Template的实现是为每一个使用Template变量编译成一个新类,这会引起一定的冗余代码。

2.Generics的定义:
2.1类和接口定义
以下是最简单的Generics类定义,定义了一个参数化类型T1:

interface MyList<T1> {….. }

以下是支持多个参数化类型的接口:

interface MyList<T1,T2,T3> {….. }

Java支持带有限制的参数化类型。在下面的例子中,T1的类型必须实现类Comparable接口,T2类型必须为Component类的子类。

interface MyList<T1 implements Comparable, T2 extends Component> {}

复杂的定义可以带有限定的声明,甚至可以使用向前引用。

class Test<A implements ConvertibleTo<B>, B implements ConvertibleTo<A>{}

对于class的定义,基本与interface相同,此处不再详述。

2.2 方法的定义
在方法中,通过定义参数化类型,可以提高方法的抽象级别,提高其可复用性。方法的参数化类型列表放在方法修饰符的后面,返回值的前面。如:

public static  <Elem> void swap(Elem[] a,int i,int j)
Elem temp=a[i];
a[i]=a[j]
a[j]=temp;
}

2.3 实际例子
一但Java语言支持了Generics,Collection中的大部分类将用Generics方式重写。例:使用Generics重写的Hashtable的定义

public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, java.lang.Cloneable, java.io.Serializable {
public V put(K key, V value) {……}
…….
}

与以前的Hashtable定义不同的是,它增加了两个用于表达Key和Value参数化类型(K,V),由于Dictionary和Map都将支持Generics,因此它们都使用Generics的表达方式。

3.Generics的使用:
3.1 创建对象
Generics类在使用之前,必须按照定义进行初始化,设置参数化类型的实际类型,以下是构造Hashtable和Vector的一些例子。

Hashtable<Integer,String> ht1=new Hashtable<Integer,String>();
Hashtable<Integer,String> ht2=null;
Vector<String> v1=new Vector<String>();
Vector<Integer> v2=new Vector<Integ

3.2 Generics对象的类
在上例中,对于v1和v2对象来说,它们都是Vector类的对象,它们有相同的Class类型,换句话说,在运行时,以下表达式为真。虽然它们使用不同的参数类型创建,但是它们的Class类型是相同的。 Assert(V1.getClass().equals(v2.getClass()));

但是,如果我们定义一个 带有Vector参数的方法,在调用该方法时,传入一个Vector的对象,这将会导致编译失败。这是因为在编译时,这两个对象被当作不同的类型。

void  method(Vector<String> v) {};

Vector<Integer> v2=new Vector<Integer>();
method(v2);//编译失败

3.3 类的强制转换
对于Generics类的强制转化的原理,我们可以使用通用的转化规则进行操作。需要注意的一点是,同一个Generics类所定义的不同参数化类型的对象之间是不能进行转化的。例如Vector和Vector之间就是不能转化的。另外,Object也不能够转化成Generics类型,但是Generics类可以转化成Object。

以下是一些转化的例子

Class Dictionary<A,B> extends Object{}
Class Hashtable<A,B> extends Dictionary<A,B> {}
Dictionary<String,Integer> d=new Dictionary<String,Integer>();
Hashtable<String,Integer> h=new Hashtable <String,Integer>();
Hashtable<Float,Double> hfd=new Hashtable<Float,Double>();
Object o=new Object();
1) d= (Dictionary<String,Integer>)h//编译成功,运行成功;它们具有父子类关系。
2) h=(Hashtable<String,Integer>)d;// 编译成功,运行失败;它们具有父子类关系。
3) h=(Hashtable<String,Integer>)o;//编译失败,Object不能转化成Generics类;
4) hfd=(Hashtable<Float,Double>)d;//编译失败;

最新文章

  1. java的覆盖重写隐藏和C#中的不同
  2. 6. js时间比较
  3. iOS多线程知识总结--GCD
  4. 20145207《Java程序设计》第6周学习总结
  5. thinkcmf thinkphp隐藏后台地址
  6. 1、Window10 Electron 开发环境搭建
  7. 【fs】
  8. 嵌入式C开发人员的最好的0x10道笔试题
  9. css两列布局,一边固定宽度,另一边自适应
  10. 在线maven 仓库
  11. Commix命令注入漏洞利用
  12. python定时发信息给女友
  13. sed用法说明
  14. js-MediumGrade-base.js
  15. Word2Vec实现原理(Hierarchical Softmax)
  16. git库上传
  17. Android Dalvik和JVM的区别
  18. gvim 全屏 插件
  19. java基础之Flex弹性布局、JSP错误处理以及Log4J
  20. go加密算法:非对称加密(二)--Hash

热门文章

  1. Kong管理UI -kong-dashboard (附kong封装webservice方法)
  2. 【转载】如何在 Github 上发现优秀的开源项目?
  3. Java常用的加密解密类(对称加密类)
  4. 关于Linux服务器磁盘空间占满问题的解决方法
  5. 2018ICPC网络赛(焦作站)K题题解
  6. Spark分析之Worker
  7. 用深度学习LSTM炒股:对冲基金案例分析
  8. 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #15 ramzswap
  9. 单元测试工具NUnit的使用
  10. Pillow 读取图片截断错误