参数化类型是不可变的。对两个不同类型T1和T2而言,List<T1>与List<T2>没有父子类型关系。

考虑:

public class Stack<E> {
public Stack();
public void push(E e);
public E pop();
public boolean isEmpty();
}

假设增加一个方法,按顺序将一系列的元素放到堆栈中:

public void pushAll(Iterable<E> src) {
for(E e : src)
push(e);
}

如果尝试这样做:

Stack<Number> s = new Stack<Number>();
Iterable<Integer> i = ...;
s.pushAll(integers);

从逻辑上讲,这样应该是允许的,因为Integer是Number的子类,应当允许将Integer放到类型为Number的堆栈中。

但实际运行的时候会提示Iterable<Number>与Iterable<Integer>不兼容。

有限制的通配符类型可以处理这种情况:

pushAll的输入参数不应该是“E的Iterable接口”,而应该为“E的某个子类型的Iterable接口”,修改为Iterable<? extends E>

假设添加一个popAll方法,从堆栈中弹出每个元素,添加到指定集合中:

public void popAll(Collection<E> dst) {
while(!isEmpty) {
dst.add(pop());
}
}

与未修改的putAll一样,应当允许类型为Number的栈帧放在包括Number在内的父类型中。

所以,修改为:

public void popAll(Collection<? super E> dst) {
while(!isEmpty) {
dst.add(pop());
}
}

在putAll方法中,输入参数的角色是生产者,因为参数提供数据给堆栈使用,在popAll方法中,输入参数的角色是消费者,因为堆栈提供数据给参数使用。总之,如果参数化类型表示一个T生产者,就使用<? extends T>,如果表示一个T的消费者,就使用<? super T>。

第28条:利用有限制通配符来提升API的灵活性的更多相关文章

  1. Item 28 利用有限制通配符来提升API的灵活性

    <? extends E> 和<? super E>的使用   <? extends E>的使用 Item 26 这是堆栈的公有API: public class ...

  2. 第二十八条:利用有限制通配符来提升API的灵活性

    如第二十五条所述,参数化类型是不可变的.类型Type1和Type2而言,不管Type1与Type2的关系,List<Type1>既不是List<Type2>的子类型,也不是也不 ...

  3. Effective Java 第三版——31.使用限定通配符来增加API的灵活性

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

  4. EffectiveJava(28)怎么利用有限制的通配符类型来提升API的灵活性

    有时候,我们需要的灵活性要比不可变类型所能提供的更多.所以针对一些通用性的方法,通常用泛型代替固定的数据类型,特别是当你要将某个方法打包成Jar的时候. 结合之前的例子,我们增加尝试用有限制的通配符类 ...

  5. effective-java学习笔记---使用限定通配符来增加 API 的灵活性31

    在你的 API 中使用通配符类型,虽然棘手,但使得 API 更加灵活. 如果编写一个将被广泛使用的类库,正确使用通配符类型应该被认为是强制性的. 记住基本规则: producer-extends, c ...

  6. MySQL必会的28条经典查询

    MySQL必会的28条经典查询   原创作品.转载请注明出处https://blog.csdn.net/kk123k 表结构及测试数据请看我上一篇文章:学生选修成绩表测试数据 Student(Sno, ...

  7. 利用 Django REST framework 编写 RESTful API

    利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framewor ...

  8. 利用Vert.x构建简单的API 服务、分布式服务

    目前已经使用Vertx已经一年多了,虽然没有太多的造诣,但也已在项目中推广了下:从最初的vertx搭建web服务,到项目上线运营,还算比较稳定.再到后来尝试搭建基于vertx的分布式服务,一路下来也积 ...

  9. jQuery:jQuery性能优化28条建议

    http://www.xue5.com/WebDev/jQuery/671700.html 直在寻找有关jQuery性能优化方面的小窍门,能让我那臃肿的动态网页应用变得轻便些.找了很多文章后,我决定将 ...

随机推荐

  1. New Features in C# 3.0, 4.0 and 5.0 (英文差的免入)

    What’s New in C# 3.0   Language Integrated Query(LINQ) - LINQ enables queries to be written in C# pr ...

  2. git在windows下clone、pull或者push内存溢出的解决办法

    发现国内使用git来真正管理源码的人不多,特别是大数据量的源码,今天使用git clone android的源码时突然出现remote out of memery,解决办法: git config - ...

  3. pomelo 开发环境搭建

    开发前提条件:  Windows系统,请确保你的Windows系统包括源代码编译工具.Node.js的源代码主要由C++代码和JavaScript代码构成,可是却用gyp工具来做源代码的项目管理,该工 ...

  4. iOS开发——Swift篇&Swift关键字详细介绍

    Swift关键字详细介绍 每一种语言都有相应的关键词,每个关键词都有他独特的作用,来看看swfit中的关键词: 关键词: 用来声明的: “ class, deinit, enum, extension ...

  5. android124 zhihuibeijing 新闻中心-新闻 -北京页签 下拉刷新

    缓存工具类:以url为key,json数据为value, package com.itheima.zhbj52.utils; import com.itheima.zhbj52.global.Glob ...

  6. [设计模式1]--单例模式(SINGLETON)

    搞笑解释: 俺有6个漂亮的老婆,她们的老公都是我,我就是我们家里的老公Sigleton,她们只要说道“老公”,都是指的同一个人,那就是我 定义: 单例模式确保某一个类只有一个实例,而且自行实例化并向整 ...

  7. Jordan Lecture Note-4: Linear & Ridge Regression

    Linear & Ridge Regression 对于$n$个数据$\{(x_1,y_1),(x_2,y_2),\cdots,(x_n,y_n)\},x_i\in\mathbb{R}^d,y ...

  8. 建索引让SQL飞起来

    今天帮助看了一个哥们的数据库,帮他抓了一下等待事件,刚好有一个sql在等待事件中,顺便看看 监控等待事件 select a.SID, a.EVENT, b.OSUSER, b.username, b. ...

  9. 新闻头条应用源码ios版

    <ignore_js_op>      源码下载:http://code.662p.com/view/13343.html     作者ymcao,源码TopNewsIOS,新闻头条IOS ...

  10. Flume简介与使用(二)——Thrift Source采集数据

    Flume简介与使用(二)——Thrift Source采集数据 继上一篇安装Flume后,本篇将介绍如何使用Thrift Source采集数据. Thrift是Google开发的用于跨语言RPC通信 ...