泛型程序设计

来源:互联网 发布:实现rsaq算法加密实例 编辑:程序博客网 时间:2024/06/07 04:06

1.为什么使用泛型程序设计
  泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用。在Java中增加泛型类之前(JDK 1.5),泛型程序设计是通过继承实现的。例如:

public class ArrayList{    private Object[] elementData;    public Object get(int i){......}    public void add(Object o){......}}

这样实现存在两个问题。
I. 当获取一个值时必须进行强制类型转换
ArrayList files = new ArrayList();
files.add(0);
files.add(1);
files.add(1.0);
files.add(“abc”);
String filenames = (String)files.get(0);
II. 缺少错误检查,可以向数组中添加任何类的对象
files.add(new File(“….”));
对于这个调用,编译和运行都不会报错。然而在其他地方,例如向下类型转换不合理、长整型转换整型损失精度等将会带来一些错误。
  泛型提供了一个更好的解决方案:类型参数。例如:
  ArrayList< String > files = new ArrayList< String>();
  编译器也可以很好的利用这个信息。当调用get时候,不需要强制类型转换,编译器就知道返回类型为String。而不是Object:
  String filename = files.get(0);
  编译器还知道ArrayList< String>中add方法中有一个类型为String的参数。这将比使用Object类型的参数更加安全。这意味着编译器可以进行检查,避免插入错误类型的对象。
2.泛型类
  一个泛型类就是具有一个或者多个类型变量的类。示例代码如下:
  

public class Pair< T >  {     private T first;     private T second;     public Pair(){         first=null;         second=null;     }     public Pair(T first,T second){         this.first = first;         this.second = second;     }     public void setFirst(T newValue){first = newValue;}     public T getFirst(){        return this.first;    }    public T getSecond(){        return this.second;    }     public void setSecond(T newValue){second = newValue;}   }

泛型类也可以有多个类型变量,可以定义Pair类,其中第一个域和第二个域使用不同的类型。例如:
  public class Pair< T, U>{…}
  用具体的类型替换类型变量就可以实例化泛型类型:Pair< String>。
  可以将结果想象成带有构造器的普通类和方法:

Pair< String>()Pair< String>(String,String)
String getFirst()String getSecond()void setFirst(String)void setSecond(String)

换句话说,泛型类可以看作普通类的工厂。
如下程序来自Java核心技术卷1,展示了静态的minmax方法遍历数组并同时计算出最小值和最大值。它用一个Pair对象返回两个结果。

public class PairTest {    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());    }}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<>(min,max);    }}

运行结果:


这里写图片描述

3.泛型方法
顾名思义,泛型方法是指带有类型参数的简单方法

class ArrayAlg{    public static <T> T getMiddle(T a){        return a[a.length/2];    }}

注意类型变量放在修饰符(这里是public static)的后面,返回类型的前面。泛型方法可以定义在普通的类中,也可以定义在泛型类中。当调用一个泛型方法时,在方法名前的尖括号放入具体类型:
  String middle = ArrayAlg.< String>getMiddle(“John”,”Q.”,”public”);
注意< String>通常可以省略。
4.类型变量的限定
  有时候,类和方法需要对类型变量加以约束。例如:

  class ArrayAlg{  public static <T> T min(T[] a){  if(a==null||a.length==0)  return null;  T smallest = a[0];  for(int i=1;i<a.length;i++)  if(smallest.compareTo(a[i])>0)  smallest = a[i];  return smallest;  }  }

该代码存在的问题在于,无法保证每个T类型的对象有compareTo方法。解决问题的方法是对类型变量T加以限定,将T限定为实现了Compareble接口(只含一个方法的compareTo的标准接口)的类。限定如下:
  public static < T extends Compareble> T min(T[] a){…}
现在,泛型的min方法只能被实现了Compareble接口的类使用(如String、Date等)的数组调用。由于例如Rectangle没有实现Compareble接口,所以调用min将会产生一个编译错误。< T extends BoundingType>表示T应该是绑定类型的子类型。T和BoundingType可以是类,也可以是接口。当用多个限定时,使用通配符“&”隔开,如:< T extends Compareble & Serializable >。示例如下:

package Generic;import java.util.Calendar;import java.util.GregorianCalendar;public class PairTest {    public static void main(String[] args) {        /*String[] words = {"Mary","had","a","little","lamb"};        Pair<String> mm= ArrayAlg.minmax(words);*/        GregorianCalendar[] birthdays = {                new GregorianCalendar(1906,Calendar.DECEMBER,9),                new GregorianCalendar(1815,Calendar.DECEMBER,10),                new GregorianCalendar(1903,Calendar.DECEMBER,3),                new GregorianCalendar(1910,Calendar.DECEMBER,22),        };        Pair<GregorianCalendar> mm = ArrayAlg.minmax(birthdays);        System.out.println("min: "+mm.getFirst().getTime());        System.out.println("max: "+mm.getSecond().getTime());    }}class ArrayAlg{    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<>(min,max);    }}


结果:这里写图片描述<\center>

*注:参考《Java核心技术卷I》第12章。*

0 0
原创粉丝点击