第30条:优先考虑泛型方法

类可以是泛型的(如List),方法也可以是独立的泛型方法。泛型方法意味着该方法可以独立于其所在类,拥有自己的类型参数,从而在更广泛的输入类型上安全地工作。
静态工具类尤其适用于泛型化,Collections中的所有算法方法都都泛型化了,例如sort等。
在这里插入图片描述

实现两个Set合并

一步步来完成,首先初步定义这个方法。

    public static Set union(Set s1, Set s2) {
        Set res = new HashSet(s1);
        res.addAll(s2);
        return res;
    }

当然这样写会有警告,为了消除警告,我们加入泛型。
在这里插入图片描述
在方法定义和返回值中添加声明类型参数的类型参数列表,并在参数、返回值、方法中使用。

    public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
        Set<E> res = new HashSet<>(s1);
        res.addAll(s2);
        return res;
    }

其实这样就算实现了一个简单的泛型方法了。
局限性是参数、返回值的类型必须相同。利用通配符类型便可以使方法更加灵活(31条会讲到)。

编写恒等函数

恒等函数:也就是传入什么,返回什么。函数式接口。可以使用Function.identity,但使用都需要新创建一个,因此我们自己使用泛型来实现一个,被擦除后就形成了一个泛型单例。

    private static UnaryOperator<Object> identity = (t) -> t;

    @SuppressWarnings("unchecked")
    public static <T> UnaryOperator<T> identity() {
        return (UnaryOperator<T>)identity;
    }

递归类型限制

类型参数必须与自身具有可比性。

public static <T extends Comparable<T>> T max(Collection<T> coll) {
    // 实现查找最大值
}

总结

总而言之,泛型方法就像泛型一样,使用起来比要求客户端转换输入参数并返回值的方法来得更加安全,也更加容易。就像类型一样,你应该确保方法不用转换就能使用,这通常意味着要将它们泛型化。并且就像类型一样,还应该将现有的方法泛型化,使新用户使用起来更加轻松,且不会破坏现有的客户端(详见第26条)。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐