java泛型示例
使用泛型机制编写的程序代码要比那些杂乱地使用Object变量,然后再进行强制类型转换的代码具有更好的安全性和可读性。
泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用。
一个泛型类就是具有一个或多个类型变量的类。
如下面的Pair例子,就是一个泛型类
package ch13genic;public class Pair<T> {private T first;private T second;public Pair(){first = null;second = null;}public T getFirst() {return first;}public void setFirst(T first) {this.first = first;}public T getSecond() {return second;}public void setSecond(T second) {this.second = second;}public Pair(T first, T second) {this.first = first;this.second = second;}}package ch13genic;public class PairTest1{ public static void main(String[] args) { String[] words = { "Mary", "had", "a", "little", "lamb" }; Pair<String> mm = ArrayAlg.minmax(words); System.out.println("min = " + mm.getFirst()); System.out.println("max = " + mm.getSecond()); String midStr = ArrayAlg.<String>getMiddle(words); //调用泛型方法,也可以省略<String>,因为编译器根据words匹配T[] a,判断出T一定是String。 System.out.println(midStr); // int[] a = {1,23,45,56,3};// int aMid = ArrayAlg.getMiddle(a); 编译出错,为什么?猜测:因为T是一个类型变量,代表的是一个类,而int只是基本类型 // Integer[] a ={1,23,45,56,3};// int aMid = ArrayAlg.getMiddle(a);// System.out.println(aMid); }}class ArrayAlg{ public static Pair<String> minmax(String[] a) { if (a == null || a.length == 0) return null; String min = a[0]; String max = a[0]; for (int i = 1; i < a.length; i++) { if (min.compareTo(a[i]) > 0) min = a[i]; if (max.compareTo(a[i]) < 0) max = a[i]; } return new Pair<String>(min, max); } public static <T> T getMiddle(T[] a){ //示意:带有类型参数的方法。由于这个类不是在泛型类中定义的,要用<T>引人类型变量,它放在修饰符和返回值之间 return a[a.length/2]; } }class ArrayAlg{public static <T> T min(T[] a) {if (a == null || a.length == 0)return null;T min = a[0];for (int i = 0; i < a.length; i++) {if (min.compareTo(a[i]) < 0)min = a[i];}return min;}}这里有一个问题,变量min的类型为T,意味着它可以是任何一个类的对象。怎么才能确信T所属的类有compareTo方法呢?public static <T extends Comparable> T min(T[] a){}实际上,Comparable本身就是一个泛型接口:public interface Comparable<T>,唯一的方法:compareTo(T o) 如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。package ch13genic;import java.util.*;public class PairTest2{ public static void main(String[] args) { GregorianCalendar[] birthdays = { new GregorianCalendar(1906, Calendar.DECEMBER, 9), // G. Hopper new GregorianCalendar(1815, Calendar.DECEMBER, 10), // A. Lovelace new GregorianCalendar(1903, Calendar.DECEMBER, 3), // J. von Neumann new GregorianCalendar(1910, Calendar.JUNE, 22), // K. Zuse }; Pair<GregorianCalendar> mm = ArrayAlg.minmax(birthdays); System.out.println("min = " + mm.getFirst().getTime()); System.out.println("max = " + mm.getSecond().getTime()); }}class ArrayAlg{ /** Gets the minimum and maximum of an array of objects of type T. @param a an array of objects of type T @return a pair with the min and max value, or null if a is null or empty */ public static <T extends Comparable> Pair<T> minmax(T[] a) { if (a == null || a.length == 0) return null; T min = a[0]; T max = a[0]; for (int i = 1; i < a.length; i++) { if (min.compareTo(a[i]) > 0) min = a[i]; if (max.compareTo(a[i]) < 0) max = a[i]; } return new Pair<T>(min, max); }}Pair<String> p = new Pair("first", "second");Pair<Integer> p1 = new Pair();System.out.println(p.getClass().getName());// ch13genic.PairSystem.out.println(p1.getClass().getName()); // ch13genic.PairList<String> l1 = new ArrayList<String>();List<Integer> l2 = new ArrayList<Integer>();System.out.println(l1.getClass().getName());// java.util.ArrayListSystem.out.println(l2.getClass().getName()); // java.util.ArrayList泛型类不能扩展Throwable。如public class Problem<T> extends Exception {try{//do work}catch(T e){ //error:Cannot use the type parameter T in a catch block//logger.info("");}}public static <T extends Throwable> void doWork(T t) throws T{//oktry{//do work}catch(Throwable e){ //error:Cannot use the type parameter T in a catch block t.initCause(e);throw t;}}不能申明参数化类型的数组,如:public Pair(T first, T second) { //errorthis.first = new T();this.second = new T();}public class Singleton<T> {private static T singleInstance; //error:Cannot make a static reference to the non-static type Tpublic static T getSingleInstance(){//errorif(singleInstance==null){//construct new instance of T}return singleInstance;}}