优先使用泛型方法

正如类可以是泛型的,方法也可以是泛型的。 对参数化类型进行操作的静态工具方法通常都是泛型的。

集合中的所有“算法”方法(如 binarySearchsort)都是泛型的。

编写泛型方法

示例代码Item30Example01.java:泛型方法示例,取两个集合的并集。

对于简单的泛型方法来说,就是这样。

泛型方法编译时不会生成任何警告,并提供类型安全性和易用性。 这是一个简单的程序来运行该方法。 这个程序不包含强制转换和编译时没有错误或警告:至少对于简单的泛型方法来说,就是这样。

恒等方法分配器

假设你想写一个恒等方法分配器( identity function dispenser)。

类库提供了 Function.identity 方法,所以没有理由编写你自己的实现,但它是有启发性的。

如果每次要求的时候都去创建一个新的恒等方法对象是浪费的,因为它是无状态的。

如果 Java 的泛型被具体化,那么每个类型都需要一个恒等方法,但是由于它们被擦除以后,所以泛型的单例就足够了。

示例代码Item30Example02.java: 恒等方法分配器( identity function dispenser)

递归类型限制

类型参数受涉及该类型参数本身的某种表达式限制是允许的。 这就是所谓的递归类型限制(recursive type bound)。

递归类型限制的常见用法与 Comparable 接口有关,它定义了一个类型的自然顺序。

public interface Comparable<T> {
    int compareTo(T o);
}

类型参数 T 定义了实现 Comparable<T> 的类型的元素可以比较的类型。

在实际中,几乎所有类型都只能与自己类型的元素进行比较。 所以,例如,String 类实现了 Comparable<String>Integer 类实现了 Comparable<Integer> 等等。

示例代码Item30Example03.java:根据其元素的自然顺序来计算集合中的最大值。

请注意,如果列表为空,则此方法将引发 IllegalArgumentException 异常。 更好的选择是返回一个 Optional<E>

限定的类型 <E extends Comparable <E >> 可以理解为「任何可以与自己比较的类型 E」,这或多或少精确地对应于相互可比性的概念。

总结

总之,像泛型类型一样,泛型方法比需要客户端对输入参数和返回值进行显式强制转换的方法更安全,更易于使用。

像类型一样,你应该确保你的方法可以不用强制转换,这通常意味着它们是泛型的。

应该泛型化现有的方法,其使用需要强制转换。

这使得新用户的使用更容易,而不会破坏现有的客户端。