Java泛型(有界通配符)
根据Joshua Bloch的《有效Java》一书,有一条关于如何/何时在泛型中使用有界通配符的规则。此规则为PECS(生产者扩展,消费者超级)。当我学习以下示例时: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
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
方法中声明参数,则传递的不是typeE
,而是扩展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>)