Java中的泛型(Generics)跟C++中的模版大同小异,都是为了简化代码,为变成提供了方便!
1.类型安全
泛型的主要目标是提高Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度
上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中。
2.消除强制类型转换
泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。
3.潜在的性能收益
泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型
转换)插入生成的字节码中。但是更多类型 信息可用于编译器这一事实,为未来版本的JVM 的优化带来可能.
JDK5以前的List操作:
类List的函数add接受一个Object参数:
1 public boolean add(java.lang.Object element);//存入的是Object对象,不能确定对象类型
类List的函数get函数从中取出一个对象:
1 public java.lang.Object get(int index) throws IndexOutOfBoundsException//取出的也是Object对象,需要强制类型转换
一般编码示例:
1 List stringList1 = new ArrayList(); 2 stringList1.add("Java 5"); 3 stringList1.add("with generics"); 4 String s1 = (String) stringList1.get(0);
如果我们能限制装入对象的数据类型,使其保持一致,就能很好的解决这个问题,这样取数据的时候将不要数据类
型的强制转化,这时泛型便应运而生。
ArrayList <String> al = new ArrayList() <String>; al.add("one"): //al.add(1);//编译不通过 Employee emp=employeeList.get(0);//不需要强制类型转换
1 /* 2 * 局限性,一旦类确定, 就必行用相同的数据类型 3 * 4 * */ 5 class Student { 6 public String getName() { 7 return "student"; 8 } 9 } 10 11 class Worker { 12 13 } 14 15 class Tool<T> { 16 private T t = null; 17 18 public void setMyClass(T t) { 19 this.t = t; 20 } 21 22 public T getMyClass() { 23 return t; 24 } 25 26 @Override 27 public String toString() { 28 return t.getClass().getName(); 29 } 30 } 31 32 public class GenClass { 33 public static void main(String[] args) { 34 Tool<Student> s = new Tool<Student>(); 35 s.setMyClass(new Student()); 36 System.out.println(s.getMyClass()); 37 } 38 }
1 /** 2 * 泛型类+泛型方法+静态泛型方法 3 */ 4 class Gen<T> { 5 /* 6 * 使用泛型类的泛型 7 */ 8 public void show(T t) { 9 System.out.println(t); 10 } 11 12 /* 13 * 泛型方法 14 */ 15 public <M> void show1(M m) { 16 System.out.println(m); 17 } 18 19 /* 20 * 静态泛型方法 21 */ 22 public static <S> void show2(S s) { 23 System.out.println(s); 24 } 25 26 } 27 28 public class GenClassAndMethod { 29 30 public static void main(String[] args) { 31 Gen.show2(123); 32 Gen<String> g = new Gen<String>(); 33 g.show("325"); 34 // g.show(123);//报错 35 g.show1(123);// √ 36 37 } 38 }
1 /** 2 * 泛型接口 3 */ 4 interface face<T> { 5 public void show(T t); 6 } 7 8 /* 9 * 实现接口的时候明确所操作的数据类型 10 */ 11 class ImpClass1 implements face<String> { 12 13 @Override 14 public void show(String s) { 15 System.out.println(s); 16 } 17 } 18 19 /* 20 * 实现接口的时候不明确所操作的数据类型 21 * 22 * 用户操作的时候在定义数据类型 23 */ 24 class ImpClass2<T> implements face<T> { 25 26 @Override 27 public void show(T s) { 28 System.out.println(s); 29 } 30 } 31 32 public class GenInterfase { 33 public static void main(String[] args) { 34 ImpClass1 impClass1 = new ImpClass1(); 35 impClass1.show("123"); 36 ImpClass2<Integer> i2 = new ImpClass2<Integer>(); 37 // i2.show("1243");//报错 38 i2.show(123); 39 }
1 package bin.ykb.advanced; 2 3 import java.util.ArrayList; 4 import java.util.Iterator; 5 6 /** 7 * 占位符 8 */ 9 10 public class Placeholder { 11 private static void show1(ArrayList<?> as) {//直接利用占位符对操作类型进行占位,对任意类型的ArrayList<> 都可以操作,原理和泛型方法差不多 12 Iterator<?> i = as.iterator(); 13 while (i.hasNext()) { 14 System.out.println(i.next()); 15 } 16 } 17 18 private static void show2(ArrayList<String> as) {// 这是为ArrayList<String>量身定做打印,没有什么扩展性 19 Iterator<String> i = as.iterator(); 20 while (i.hasNext()) { 21 System.out.println(i.next()); 22 } 23 } 24 25 public static void main(String[] args) { 26 ArrayList<String> as = new ArrayList<String>(); 27 as.add("a"); 28 as.add("b"); 29 as.add("c"); 30 31 ArrayList<Integer> ai = new ArrayList<Integer>(); 32 ai.add(1); 33 ai.add(2); 34 ai.add(3); 35 36 show1(as); 37 show1(ai); 38 System.out.println("============"); 39 show2(as); 40 // show2(ai); 41 } 42 }
最后就是泛型限定。
<? extends Person> 参数只能是Person或Person 类的子类
<? super Person> 参数只能是Person,或Person类的父类
参见java.util.Collections 中的方法
public static <T> boolean addAll(Collection<? super T> c, T... elements)
参考:
http://blog.csdn.net/jiang_bing/article/details/6912115
转载请注明出处:
博客园_yokoboy
http://www.cnblogs.com/yokoboy/archive/2012/07/25/2608165.html