步步理解 JAVA 泛型编程(三)

前面介绍的无论是泛型类还是泛型方法,基本上都是把定义的类型参数作为一个整体来操作,放到数组或取出来,顶多就是调用了一下 hashCode() 方法,因为这是 Java 的根对象拥有的方法。比如说一个泛型数组,要得到其中的最小元素:

在上面的代码中,要比较大小,所以调用了类型 T 的 compareTo() 方法,我们期望具体类型是一个实现了 compareTo() 方法的类型。不过,很可惜,Java 泛型还是与 C++ 的模板有别,在  C++ 中真的对于类似上面的代码,具体类型有 compareTo() 则可以通过,具体类型没有 compareTo() 则不能通过,是推延至使用代码时确定具体类型是否满足条件。而在 Java 中无论你的具体类型是什么,上面的代码本身就是无法编译通过的,错误为:

The method compareTo(T) is undefined for the type T

也就是说在你编写泛型的时候就该限类型参数的一个更窄的范围,不是所有的 Object,而是那些实现了 compareTo() 方法的类型,比如说实现了 Compareable 接口的类型。为了做到这一点,对于前面方法声明部分就要做如下进一步约束:

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

这里只表示到时的具体类型 T 是 Comparable 的一种类型,extends 后是接口,还是类都是用 extends 关键字,不在此区分接口还是类,只表示 Is-A 的关系。

这样你在使用该泛型的时候具体类型一定要是实现了 Comparable 接口的类型,比如用这样的代码 ArrayAlg.main(new Object[]{"1","2","3"}); 调用,则会有下面的错误提示:

Bound mismatch: The generic method main(T[]) of type ArrayAlg is not applicable for the arguments (Object[]). The inferred type Object is not a valid substitute for the bounded parameter <T extends Comparable> ArrayAlg.java

因为 Object 并未实现 Comparable,用 ArrayAlg.main(new String[]{"1","2","3"}); 调用则无误,String 是实现了 Comparable 接口的。

如果在泛型实现中会调用到多个方法,要求泛型参数同属不同的类型,就 extends 多个接口或类,中间用 & 符号隔开。

public static <T extends Comparable & Serializable> T foo(T[] a){
       //a[i].compareTo(a[i-1]);
       //xxx.writeObject(a[i]);
}

为什么是用 & 而不用逗号(,) 呢,因为逗号还有作他用,当有多个类型参数时就该写作:

public static <T extends Comparable & Serializable, U extends Runnable> T foo(T a, U b){
       //a[i].compareTo(a[i-1]);
       //xxx.writeObject(a[i]);
       //new Thread(u).start();
}

虽然这里简单的用 extends 统一的表示了原有的 extends 和 implements 的概念,但仍要遵循应用的体系,Java 只能继承一个类,可以实现多个接口,所以你的某个类型需要用 extends 限定,有多种类型的时候,只能存在一个是类,而且参考变参的做法,类写在第一位,接口列在后面,也就是:

<T extends SomeClass & interface1 & interface2 & interface3>

这里的例子仅演示了泛型方法的类型限定,对于泛型类中类型参数的限制用完全一样的规则,只是加在类声明的头部,如:

public class Demo<T extends Comparable & Serializable>{

      //该泛型类中就可以用 Comparable 声明的方法和 Seriablizable 所拥有的特性了
}

多个类型参数的情况类推就是了。

本文链接 https://yanbin.blog/understand-java-generic-3/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

3 Comments
Inline Feedbacks
View all comments
xingqing
xingqing
13 years ago

好东西,分享了一下

俏物悄语
14 years ago

学习,真是好东西

税国政
税国政
14 years ago

继续学习中。。。。