范型程序设计 - core java 7

13. 范型程序设计 - core java 7

13.2 简单的范型类的定义

例如Pair类:
public class Pair<T> {
    T first;
    T second;
    //...
}

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

使用的时候:
Pair<String> ps = ...


13.3 范型方法

例如:
class ArrayAlg {
    public static <T> T getMiddle(T[] a) {  //将类型变量放在方法的返回类型之前.
        return a[a.length/2]);
    }
}
使用的时候如:
String [] names = {"abc", "xyz" };
String s = ArrayAlg.<String>getMiddle(names);  //类型实参放在函数名之前.
实际上这里的<String>可以省略. 因为可以从参数推出来. 通常写为:
String s = ArrayAlg.getMiddle(names);


13.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限制为 Comparable接口 的子类型. 改为:
public static <T extends Comparable> T min(T[] a) { ... }
当有多个限制类型时如下:
T extends Comparable & Serializable
用&把多个限制类型分隔开. 这些限制类型可以是类或接口. 如果有类只会有一个类是限制类型. 因为Java
不允许多继承. 类要写在第一个限制类型处.


13.5 范型代码和虚拟机

在Java虚拟机中实际上并没有范型类.这不同与c++中范型. c++范型代码实例化会带来代码膨胀.Java的不会.
在虚拟机中只是用原始的Object类或第一个限制类型来表示该类中用到的实际类型.
例如前边的Pair<T>会被表示为:
public class Pair {
    Object first;
    Object second;
}

class ArrayAlg {
    public static <T extends Comparable> T min(T[] a) {...}
}
被表示为原始类型:
class ArrayAlg {
    public static Comparable min(Comparable[] a) {...}
}

可见在虚拟机中并没有范型. 只有普通的类和方法. 范型类或方法中所有的类型参数都会用它们的父类型表示.
所以使用范型类或方法时. 不能用基本类型(如int)来作类型实参.只能使用它们的包装类型(如Double).

而且对范型类的运行时类型查询实际上都是在查询该范型类的内部表示的类.如:
Pair<String> sp = ...
Pair<Double> dp = ...
if (sp.getClass() == dp.getClass()) ...
这个比较结果为True. 因为两个getClass返回的实际都是 Pair.class

范型类型也不能有数组. 如:
Pair<String>[] arr = ..  //错误


//跳过~~~~~ 明天继续下一章~~~~~

你可能感兴趣的:(范型程序设计 - core java 7)