Java中的泛型程序设计

来源:互联网 发布:软件项目标书 编辑:程序博客网 时间:2024/05/18 17:26

泛型程序设计(Generic programming)意味着编写的代码可以被很多不同的类型的对象所重用。
使用泛型机制编写的程序代码要比那些杂乱地使用Object变量然后再进行强制类型转换的代码具有更好的安全性和可读性。泛型对于集合类特别有用,像ArrayList就是一个无处不在的集合类。

泛型提供了一个很好的方案:
类型参数(type parameters)ArrayList类有一个类型参数来指示元素的类型

ArrayList<String> files=new ArrayList<>();

这样的代码具有很好地可读性,人们一下就能知道这个ArrayList中的元素是什么类型的了。
这也正是类型参数的魅力所在,除此之外还有安全性。

get的时候不需要进行强制类型转换编译器就能知道返回值类型为String

String filename=files.get(0);

另外ArrayList的add方法只能插入String类型的对象,编译器会进行检查,避免插入错误的类型

1、一个最简单的泛型类

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

使用的时候如下

 Pair<String> pair= new Pair<>("大雄", "静香");

注意:泛型类可以有多个类型变量。例如可以定义Pair类第一个域和第二个域使用不同的类型

public class Pair<T,U>{...}

2、泛型方法

除了泛型类还有泛型方法
简单的泛型方法如下:

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

泛型方法可以定义在普通类中也可以定义在泛型类中
当调用一个泛型方法时,在方法名前的尖括号中放入具体的类型。使用的方法如下:

 String middle = ArrayAlg.<String>getMiddle("magicwo", "嗯哼", "陈独秀", "李大钊");

绝大多数情况下,方法调用中可以省略String类型参数,编译器有足够的信息判断出所调用的方法。它用names的类型(即String[ ])与泛型类型T[ ]进行匹配并推断出T一定是String。也就是可以这样调用

 String middle = ArrayAlg.getMiddle("magicwo", "嗯哼", "陈独秀", "李大钊");

3、类型变量的限定

类或者方法需要对类型变量加以约束。怎么实现呢?可以通过对类型变量T设置限定(bound)实现这一点:

public static <T extends Comparable> T min(T[] a)...

这样 一来,泛型的min方法只能被实现了Comparable接口的类,如String、LocalDate等的数组调用。如果是Rectangle类,由于没有实现Comparable接口,所以调用min将会产生一个编译错误。

注意:这里对接口的继承为什么用的是extends而不用implements?
下面的记法

<T extends BoundingType>

表示T应该是绑定类型的子类型。T和绑定类型可以是类,也可以是接口。选择关键字extends的原因是更接近子类的概念。并且java的设计者不打算在语言中添加新的关键字。
一个类型便利那个或者通配符可以是多个限定。例如:

T extends Comparable & Serializable

4、Java泛型中的一些约束和局限

1、不能用基本类型实例化类型参数

byte、short、int、long、float、double、char、boolean这八种基本类型

2、运行时类型查询只适用于原始类型

if(a instanceof Pair<String>)if(a instanceof Pair<T>)

实际上仅仅测试a是否是任意一个类型的一个Pair。
用getClass方法也总是返回原始类型,Pair.class

3、不能创建

原创粉丝点击