泛型的介绍——详细出处参考http://liyanblog.cn/articles/2012/11/01/1351757228794.html
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
Java语言引入泛型的好处是安全简单。泛型的好处是在编译的时候检查类型安全(泛类型之前没有),并且所有的强制转换都是自动和隐式的,提高代码的重用率。
泛型在使用中还有一些规则和限制:
1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。
3、泛型的类型参数可以有多个。
4、泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上成为“有界类型”。
5、泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName(Java.lang.String);
C++泛型与Java泛型——详细出处参考http://hi.baidu.com/wolongxzg/item/e66b9bd14f5a6c362b35c7b0
C++的泛型和Java的泛型 在泛型的实现上,C++和Java有着很大的不同, Java是擦拭法实现的 C++是膨胀法实现的 因为Java原本实现就是泛型的,现在加入型别,其实是"窄化",所以采用擦拭法,在实现上,其实是封装了原本的 ArrayList,这样的话,对于下边这些情况,Java的实现类只有一个。
ArrayList<Integer> ...; public class ArrayList
ArrayList<String> ...; --同上--
ArrayList<Double> ...; --同上--
而C++采用的是膨胀法,对于上边的三种情况实际是每一种型别都对应一个实现,实现类有多个
list<int> li; class list; //int 版本
list<string> ls; class list; //string 版本
list<double> ld; class list; //double 版本
这就造成了,在序列化后,Java不能分清楚原来的ArrayList是 ArrayList<Integer>还是ArrayList
多说无益,还是看代码
class GenItems<T1, T2, T3> { private T1 firstObj; private T2 secondObj; private T3 thirdObj; public GenItems(T1 obj1, T2 obj2, T3 obj3){ firstObj = obj1; secondObj = obj2; thirdObj = obj3; } public void setFirstObj(T1 obj1){ firstObj = obj1; } public T1 getFirstObj(){ return firstObj; } public void setSecondObj(T2 obj2){ secondObj = obj2; } public T2 getSecondObj(){ return secondObj; } public void setThirdObj(T3 obj3){ thirdObj = obj3; } public T3 getThirdObj(){ return thirdObj; } } class Item { Item(){} private String item_name; Item(String item_name){ this.item_name = item_name; } public String toString(){ return item_name; } } class SubItem extends Item{ private String sub_name; SubItem(String sub_name){ this.sub_name = sub_name+"_sub"; } public String toString(){ return sub_name; } } public class GenericTest{ public static void main(String[] args){ GenItems<String, Integer, Double> items1 = new GenItems<String, Integer, Double>("Java", 15, 79.89); System.out.println(items1.getFirstObj()); items1.setFirstObj("C++"); System.out.println(items1.getFirstObj()); Item item1 = new Item("Item1"); Item item2 = new Item("Item2"); SubItem sub_item1 = new SubItem("Item1"); SubItem sub_item2 = new SubItem("Item2"); GenItems<String, Item, Item> items2 = new GenItems<String, Item, Item>("Test", item1, item2); System.out.println(); System.out.println(items2.getFirstObj()); System.out.println(items2.getSecondObj()); System.out.println(items2.getThirdObj()); GenItems<?, ?, ?> items3 = new GenItems<String, Item, SubItem>("? 无界通配符", item1, sub_item1); System.out.println(); System.out.println(items3.getFirstObj()); System.out.println(items3.getSecondObj()); System.out.println(items3.getThirdObj()); GenItems<String, ? extends Item, ? extends Item> items4 = new GenItems<String, Item, SubItem>("? extends上界通配符", item2, sub_item2); System.out.println(); System.out.println(items4.getFirstObj()); System.out.println(items4.getSecondObj()); System.out.println(items4.getThirdObj()); GenItems<String, ? super SubItem, ? super SubItem> items5 = new GenItems<String, Item, SubItem>("? super下界通配符", item1, sub_item2); System.out.println(); System.out.println(items5.getFirstObj()); System.out.println(items5.getSecondObj()); System.out.println(items5.getThirdObj()); boolean why1 = items1 instanceof GenItems<?, ?, ?>; boolean why2 = items2 instanceof GenItems<?, ?, ?>; boolean why3 = items3 instanceof GenItems<?, ?, ?>; boolean why4 = items4 instanceof GenItems<?, ?, ?>; System.out.println(); System.out.println("运行时消除erasure机制"); System.out.println(why1); System.out.println(why2); System.out.println(why3); System.out.println(why4); } }
在贴出结果之前,其中还有几个重要的泛类型概念要解释一下(摘自Java编程艺术——高永强著):
无界通配符<?>,可用来表示一个参数,匹配任何类型;
上界通配符<? extends T>,限定参数类型必须是包括T在内的子类元素,否则非法;
下界通配符<? super T>,限定元素类型必须是包括T在内的超类元素,否则为非法;
运行时消除erasure,Java再利用泛类型技术时使用运行司消除机制,即所有类型参数信息(包括类型参数和各种通配符)在运行时全部清除,但加入了造型机制(这个不懂,哪位高手指点下,谢谢先)。
上述代码运行结果如下:
Java C++ Test Item1 Item2 ? 无界通配符 Item1 Item1_sub ? extends上界通配符 Item2 Item2_sub ? super下界通配符 Item1 Item2_sub 运行时消除erasure机制 true true true true
为保证类型安全,在使用JDK1.5编译没有使用泛类型创建集合、并增添元素的代码时,将产生警告信息,提示在增添操作中存在类型不安全问题。另外,在通配符的应用提供限定上、下界,并限定不允许在通配符创建的集合中使用add()增添元素等,也进一步保障了集中的类型安全性。