Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java泛型(有界通配符)_Java_Generics_Bounded Wildcard_Effective Java_Pecs - Fatal编程技术网

Java泛型(有界通配符)

Java泛型(有界通配符),java,generics,bounded-wildcard,effective-java,pecs,Java,Generics,Bounded Wildcard,Effective Java,Pecs,根据Joshua Bloch的《有效Java》一书,有一条关于如何/何时在泛型中使用有界通配符的规则。此规则为PECS(生产者扩展,消费者超级)。当我学习以下示例时: Stack<Number> numberStack = new Stack<Number>(); Iterable<Integer> integers = ... ; numberStack.pushAll(integers); 但是如果我有下面的例子会发生什么呢 Stack<Integ

根据Joshua Bloch的《有效Java》一书,有一条关于如何/何时在泛型中使用有界通配符的规则。此规则为PECS(生产者扩展,消费者超级)。当我学习以下示例时:

Stack<Number> numberStack = new Stack<Number>();
Iterable<Integer> integers = ... ;
numberStack.pushAll(integers);
但是如果我有下面的例子会发生什么呢

Stack<Integer> integerStack = new Stack<Integer>();
Iterable<Number> numbers = ... ;
integerStack.pushAll(numbers);
根据PECS的规定,上述声明是错误的。但是我想要一个
堆栈
整数
s并传递给这个
堆栈
一个
数字
。为什么不做呢?
为什么我总是要使用
extends
关键字?为什么使用
super
是错误的?
当然,这也代表了消费者的观点。为什么消费者总是
超级



PS:更具体地说,您可以在参考书的“第28项”部分找到上述示例。

当您声明一个
堆栈时,您指的是一个Foo堆栈或Foo的子类。例如,您希望能够将
字符串
放入
堆栈
。另一种方法是不正确的,您应该不能在
堆栈中插入另一个对象


在您的示例中,您声明了一个
堆栈
。您应该能够在此堆栈中放入整数,但不能放入其他数字(如双精度),如果您在声明
堆栈时声明参数
,您会这样做,您指的是Foo的堆栈或Foo的子类。例如,您希望能够将
字符串
放入
堆栈
。另一种方法是不正确的,您应该不能在
堆栈中插入另一个对象


在您的示例中,您声明了一个
堆栈
。您应该能够在此堆栈中放入整数,但不能放入其他数字(如双精度),如果您在
pushAll
方法中声明参数
,则传递的不是type
E
,而是扩展
E
的任何类型。因此,您可以传递扩展了
Number
类型的任何
Iterable
,而不是传递
Number
Iterable

原始示例使用了
Number
类型,因为您可以传递属于
Number
子类的任何类型,如
Integer
BigDecimal


在您的示例中,您正以相反的方式进行操作。您正在使用
整数
声明您的
堆栈
。因此,
pushAll
将只能接受扩展为
Integer
的类。您将无法使用
数字
(或任何其他类,因为
整数
是最后一个类)。

pushAll
方法中,您传递的不是类型
E
,而是扩展
E
的任何类型。因此,您可以传递扩展了
Number
类型的任何
Iterable
,而不是传递
Number
Iterable

原始示例使用了
Number
类型,因为您可以传递属于
Number
子类的任何类型,如
Integer
BigDecimal


在您的示例中,您正以相反的方式进行操作。您正在使用
整数
声明您的
堆栈
。因此,
pushAll
将只能接受扩展为
Integer
的类。您将无法使用
数字
(或任何其他类,因为
整数
是最后一个类)。

尝试在堆栈中存储任意数字是不可能的,因为数字可能是整数以外的东西。所以你的例子没有多大意义

当对象AST作为使用者时,即当对象的泛型类型的实例作为参数传递给对象的方法时,您将使用super。例如:

 Collections.sort(List<T>, Comparator<? super T>)

Collections.sort(List,Comparator尝试在堆栈中存储任意数字是不可能的,因为数字可能不是整数。因此您的示例没有多大意义

当对象AST作为使用者时,即当对象的泛型类型的实例作为参数传递给对象的方法时,您将使用super。例如:

 Collections.sort(List<T>, Comparator<? super T>)

Collections.sort(List,Comparator首先要注意的是Integer扩展了Number,所以不应该将Number对象推入整数堆栈中。但是,第一个示例将处理Integer、float、BigDecimal和所有其他Number子类。

首先要注意的是Integer扩展了Number,所以不应该推Number对象但是,第一个示例将处理整数、浮点、BigDecimal和所有其他数字子类。

您的示例没有多大意义。像
这样的构造您的示例没有多大意义。像
这样的构造在推送时-您充当顾问,而不是生产者,因此您需要使用super-keyword.根据《我是生产者》一书,注释“作为E生产者的参数的通配符类型”是由编写者编写的。编写者说,当我提取堆栈时,我是消费者!前两个示例来自该书(复制粘贴).第三个例子是我的。当你推-你作为一个顾问,而不是制作人,所以你需要使用super关键字。根据《我是制作人》一书,注释“作为E制作人的参数的通配符类型”是作者写的。作者说,我是一个消费者,当我为堆栈拉!前两个样本是从书(复制粘贴)。第三个例子是我的。
 Collections.sort(List<T>, Comparator<? super T>)