跟我学(Effective Java 2)第27条:优先考虑泛型方法

本文探讨了如何在Java编程中优先考虑使用泛型方法,以提高类型安全性和代码可读性。通过示例展示了如何将Collections的算法方法泛型化,以及如何利用类型推导简化代码。此外,还介绍了泛型方法的灵活性,如有限制的通配符类型,以及如何通过泛型静态工厂方法消除类型参数的冗余。最后,提到了泛型单例工厂模式在创建不可变对象时的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

就如类可以从泛型中受益一般,方法也一样。静态工具方法尤其适合于泛型化。Collections中所有“算法”方法是泛型化的。

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

这个方法会出现两条警告,因为使用的是原生态类型。为了修正这些警告,使方法变成类型安全的,我们这里就可以用到泛型:

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

至少对于简单的泛型方法而言,就是这么回事了。现在改方法编译时不会产生任何警告,并提供了类型安全性,也更容易使用。以下是一个执行该方法的简单程序。程序不包含装换,编译时不会有错误或者警告:

public static void main(String[] args){
    Set<String> guys =new HashSet<String>{
        Array.asList("Tom","Dick","Harry"));

    Set<String> stooges =new 

HashSet<String>{
        Array.asList("Larry","Moe","Curly"));

    Set<String> aflCio=unioc(guys,stooges);
    System.out.printle(aflCio);
    }
}

运行这段程序是,会打印出[Moe,Harry,Tom,Curly,Larry,Dick]。 元素的顺序是依赖于实现的。

union方法局限在于,三个集合的类型(两个输入参数及一个返回值)必须全部相同。利用有限制的通配符类型可以使这个方法变得更回灵活。

泛型方法的一个显著特征是,无需明确指定类型参数的值,不像调用泛型构造器的时候是必须指定的。对于上述程序而言,编译器发现uniond的两个参数都是Set< String>类型,因此知道类型参数E必须为String,这个过程称作为类型推导(type inference)。

如第一条所述,可以利用泛型方法调用所提供的类型推导,是创建参数化类型实例的过程变得更加轻松。提醒一下:在调用泛型构造器的时候,要明确传递类型参数的值可能有点麻烦。类型参数出现在了变量的声明的左右两边,显得有些冗余:

Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

为了消除冗余,可以编写一个泛型静态工厂方法,与想要使用的每个构造器相对应。例如,下面是一个无参的HashMap构造器相对应的泛型静态工厂方法:

public static <K, V> HashMap<K, V> newHashMap() {
    return new HashMap<K, V>();

}

Map<String,List<String>> anagrans=newHashMap(); 

相关的模式泛型单例工厂。有时,会需要创建不可变但又适合于许多不同类型的对象。 由于泛型是通过擦除来实现的,可以给所有的必要的类型参数使用同一个单个对象,但是需要编写一个静态的工厂方法,重复地给每个必要的类型参数分发对象。这种模式叫做“泛型单例工厂”,这种模式最常用于函数对象。 如Collections.reverseOrder,但也适用于像Collections.emptySet这样的集合。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值