Get and Put Principle

PECS stands for producer-extends(? extends T), consumer-super(? super T).

  1. 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的更多相关文章

  1. 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 ...

  2. 《Effective Java》读书笔记 - 5.泛型

    Chapter 5 Generics Item 23: Don't use raw types in new code 虽然你可以把一个List<String>传给一个List类型(raw ...

  3. Effective Java 目录

    <Effective Java>目录摘抄. 我知道这看起来很糟糕.当下,自己缺少实际操作,只能暂时摘抄下目录.随着,实践的增多,慢慢填充更多的示例. Chapter 2 Creating ...

  4. 【Effective Java】阅读

    Java写了很多年,很惭愧,直到最近才读了这本经典之作<Effective Java>,按自己的理解总结下,有些可能还不够深刻 一.Creating and Destroying Obje ...

  5. Effective Java 第三版——28. 列表优于数组

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. Effective Java 第三版——26. 不要使用原始类型

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. Effective Java 第三版——30. 优先使用泛型方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. Effective Java 第三版——33. 优先考虑类型安全的异构容器

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  9. Effective Java 第三版——37. 使用EnumMap替代序数索引

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

随机推荐

  1. IT168关于敏捷开发采访

    1.我们知道敏捷开发是一套流程和方法的持续改进,通过快速迭代的方式交付产品,从而控制和降低成本.但是在实行敏捷初期,往往看不到很好的效果.这里面,您觉得问题主要出在哪?团队应如何去解决问题?金根:我认 ...

  2. js-对象-2

    对象: 对象是一组具有属性和方法的经过组织的数据. 默认对象: 日期对象:(日期基线:1970年1月1日00:00:00) 建立日期对象(实例): 格式:日期对象名称=new Date([日期参数]) ...

  3. 如何彻底的卸载和删除Windows service

    最近遇到很头疼的问题,安装到服务器的Windows Service卸载的时候出错了,结果在服务列表中就一直驻留,并且系统进程一直在运行,怎么都杀不掉. 最后终于找到办法了: 1.常规做法,批处理命令卸 ...

  4. Qt Style Sheet实践(二):组合框QComboBox的定制

    导读 组合框是一个重要且应用广泛的组件,一般由两个子组件组成:文本下拉单部分和按钮部分.在许多既需要用户选择.又需要用户手动输入的应用场景下,组合框能够很好的满足我们的需求.如我们经常使用的聊天软件Q ...

  5. 重构第25天 引入契约设计(Introduce Design By Contract checks)

    理解:本文中的”引入契约式设计”是指我们应该对应该对输入和输出进行验证,以确保系统不会出现我们所想象不到的异常和得不到我们想要的结果. 详解:契约式设计规定方法应该对输入和输出进行验证,这样你便可以保 ...

  6. WebApi传参总动员(填坑)

    本以为系列文章已经Over,突然记起来前面留了个大坑还没填,真是自己给自己挖坑. 这个坑就是: (body 只能被读取一次)Only one thing can read the body MVC和W ...

  7. ASP.NET 取得 Uri 各项属性值

    Uri uri = new Uri("http://www.yoercn.com/aboutus/idea.html");string Host = uri.Host;       ...

  8. 使用Dhcpstarv解决DHCP服务器冲突问题

    场景: 内网环境需要开启多个DHCP服务器,分别给不同的设备进行PXE安装. 存在的问题: 多个DHCP的情况下,设备在启动时随机从一个DHCP服务器获取IP(哪个DHCP服务器先响应就从哪个获取)并 ...

  9. PHP redis Api 中文文档

    phpredis是php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系 很有用;以下是redis官方提供的命令使用技巧: 下载地址如下: https://github.com/ow ...

  10. ASP.NET Boilerplate 深入系列之:概述

    因为项目需要,最近个人购买了一直在研究的ABP框架的一个Regular Licience,马上要用到一个实际的项目中,为了能够准确把握该框架涉及到设计思想.使用模式.内在实现细节.准备在接下来的一个月 ...