Effective Java 28 Use bounded wildcards to increase API flexibility
Get and Put Principle
PECS stands for producer-extends(? extends T), consumer-super(? super T).
- For maximum flexibility, use wildcard types on input parameters that represent producers or consumers.
// Wildcard type for parameter that serves as an E producer
public void pushAll(Iterable<? extends E> src) {
for (E e : src)
push(e);
}
// Wildcard type for parameter that serves as an E consumer
public void popAll(Collection<? super E> dst) {
while (!isEmpty())
dst.add(pop());
}
Although lists can both consume and produce values, the reduce method uses its list parameter only as an E producer, so its declaration should use a wildcard type that extends E. The parameter f represents a function that both consumes and produces E instances, so a wildcard type would be inappropriate for it. Here's the resulting method declaration:
// Wildcard type for parameter that serves as an E producer
static <E> E reduce(List<? extends E>list, Function<E> f, E initVal)
2. Do not use wildcard types as return types.
public static <E> Set<E> union(Set<? extends E> s1, Set<? extends E> s2)
3. If the user of a class has to think about wildcard types, there is probably something wrong with the class's API.
4. Use explicit parameter for the generic method.
Set<Integer> integers = ... ;
Set<Double> doubles = ... ;
Set<Number> numbers = union(integers, doubles);
Set<Number> numbers = Union.<Number>union(integers, doubles);
Always use Comparable<? super T> in preference to Comparable<T>.The same is true of comparators, so you should always use Comparator<? super T> in preference to Comparator<T>.
public static <T extends Comparable<? super T>> T max(List<? extends T> list)
5. If a type parameter appears only once in a method declaration, replace it with a wildcard for its simplify.
// Two possible declarations for the swap method
public static <E> void swap(List<E> list, int i, int j);
public static void swap(List<?> list, int i, int j);
// Use this one instead of first one. But this one will not compile since the one above cannot set an element
// to the list object whose type is List<?> unless the object is null.
// And you should provide clean API list the code below.
public static void swap(List<?> list, int i, int j) {
swapHelper(list, i, j);
}
// Private helper method for wildcard capture
private static <E> void swapHelper(List<E> list, int i, int j) {
list.set(i, list.set(j, list.get(i)));
}
Summary
Using wildcard types in your APIs, while tricky, makes the APIs far more flexible. If you write a library that will be widely used, the proper use of wildcard types should be considered mandatory. Remember the basic rule: producer-extends, consumer-super(PECS). And remember that all comparables and comparators are consumers.
Effective Java 28 Use bounded wildcards to increase API flexibility的更多相关文章
- Effective Java Index
Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...
- 《Effective Java》读书笔记 - 5.泛型
Chapter 5 Generics Item 23: Don't use raw types in new code 虽然你可以把一个List<String>传给一个List类型(raw ...
- Effective Java 目录
<Effective Java>目录摘抄. 我知道这看起来很糟糕.当下,自己缺少实际操作,只能暂时摘抄下目录.随着,实践的增多,慢慢填充更多的示例. Chapter 2 Creating ...
- 【Effective Java】阅读
Java写了很多年,很惭愧,直到最近才读了这本经典之作<Effective Java>,按自己的理解总结下,有些可能还不够深刻 一.Creating and Destroying Obje ...
- Effective Java 第三版——28. 列表优于数组
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——26. 不要使用原始类型
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——30. 优先使用泛型方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——33. 优先考虑类型安全的异构容器
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——37. 使用EnumMap替代序数索引
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
随机推荐
- Redis设计与实现-客户端服务端与事件
事件 redis服务器是事件驱动的,事件分为文件事件与时间事件 文件事件是服务器通过套接字与客户端连接,两者之间的通信会产生相应的文件事件,服务器监听并处理这些事件完成网络操作: 时间事件是指redi ...
- ASP.NET MVC5--Contains
前言: * The Contains method is run on the database, not the c# code above. On the database, Contains ...
- .NET生成缩略图并下载
缩略图:比喻一张图片宽度为1000px,大小为800K,经过缩略后变成一张宽度100px,大小10K的图片. 先给出界面: 总体的流程分5步如下图: 1.添加一个html:GetminPic.html ...
- C#设计模式——桥接模式(Bridge Pattern)
一.概述在软件开发中,我们有时候会遇上一个对象具有多个变化维度.比如对汽车对象来说,可能存在不同的汽车类型,如公共汽车.轿车等,也可能存在不同的发动机,如汽油发动机.柴油发动机等.对这类对象,可应用桥 ...
- sql server索引功能资料
无论何时对基础数据执行插入.更新或删除操作,SQL Server 数据库引擎都会自动维护索引.随着时间的推移,这些修改可能会导致索引中的信息分散在数据库中(含有碎片).当索引包含的页中的逻辑排序(基于 ...
- c语言笔试题(带答案)
填空: 1,short int a[10]={123, 456, 789}; sizeof(a)= 对于64位机来说,指针为8字节表示.其中 sizeof是一运算符,返回编译器为其分配的数组空间大小, ...
- [moka同学摘录]iptables防火墙规则的添加、删除、修改、保存
文章来源:http://www.splaybow.com/post/iptables-rule-add-delete-modify-save.html 本文介绍iptables这个Linux下最强大的 ...
- C语言范例学习03-中
栈和队列 这两者都是重要的数据结构,都是线性结构.它们在日后的软件开发中有着重大作用.后面会有实例讲解. 两者区别和联系,其实总结起来就一句.栈,后进先出:队列,先进先出. 可以将栈与队列的存储空间比 ...
- PHP生成图片验证码demo【OOP面向对象版本】
下面是我今天下午用PHP写的一个生成图片验证码demo,仅供参考. 这个demo总共分为4个文件,具体代码如下: 1.code.html中的代码: <!doctype html> < ...
- Vue计算属性
github地址:https://github.com/lily1010/vue_learn/tree/master/lesson06 一 计算属性定位 当一些数据需要根据其它数据变化时,这时候就需要 ...