Java Generics (bounded wildcards)
根据Joshua Bloch的"有效Java"一书,有一个关于如何/何时使用泛型中的有界通配符的规则。这条规则是PECS(生产者扩展,Comsumer Super)。当我研究以下例子时:
1 2 3 | Stack<Number> numberStack = new Stack<Number>(); Iterable<Integer> integers = ... ; numberStack.pushAll(integers); |
我知道这个规则非常适合这个例子。我必须将方法
1 2 3 4 5 6 7 | // Wildcard type for parameter that serves as an E producer public void pushAll(Iterable<? extends E> src) { for (E e : src) { push(e); } } |
号
但是如果我有下面的例子会发生什么呢?
1 2 3 | Stack<Integer> integerStack = new Stack<Integer>(); Iterable<Number> numbers = ... ; integerStack.pushAll(numbers); |
我必须按以下方式申报
1 2 3 4 5 6 | public void pushAll(Iterable<? super E> src) { for (E e : src) { push(e); } } |
。
根据PECS规则,上述声明是错误的。但我想得到一个
附:更具体地说,你可以在参考书的"第28项"部分找到上述例子。
当您声明一个
在您的示例中,您声明一个
试图在堆栈中存储任意数字是不可能的,因为一个数字可能是另一个整数。所以你的例子没有多大意义。
当对象asts作为使用者时,即当对象的泛型类型的实例作为参数传递给对象的方法时,可以使用super。例如:
1 |
在本例中,sort方法从集合中获取T实例,并将它们作为参数传递给comparator的
与您的第一个例子相比,在这个例子中,不可重复的
你的例子没有多大意义。像
在您的示例中,您声明了通用类型
因此,如果您想要声明通用类型
首先要注意的是,整数扩展了数字,所以不应该将数字对象推到整数堆栈中。但是,第一个示例将处理整数、浮点数、bigdecimal和所有其他数字子类。
在
原始示例使用
在您的示例中,您是以另一种方式进行的。你用