public void pushAll(Iterable<E> src) {
for (E e : src) {
//....
}
}
Integer是Number的子類,但是這卻編譯不過
Stack<Number> numberStack = new Stack<>();
Iterable<Integer> integers = ...;
numberStack.pushAll(integers)
我們需要將pushAll給改動一下
public void pushAll(Iterable<? extends E> src) {
for (E e : src) {
//....
}
}
這就比較合適了
如果需要區分生產者和消費者的時候,通配符的作用就很大了,這讓我們的編譯很乾淨。 PECS 代表: producer-extends,consumer-super。
舉個例子,如果是push方法,我們生成Stack中的元素,所以<? extends E>。如果是pop方法,我們消耗Stack中的元素,<? super E>。這是一種很簡單的面向對象的思維。
但是如果同時是消費和生產著,千萬不要用通配符,你需要特定一個清晰的類型匹配。
一個好玩的東西
public static <T extends Comparable<T>> T max(List<T> list)
這個該怎麽改呢
這個樣子,理解一下。
public static <T extends Comparable<? super T>> max(List<? extends T> list)
PECS,所有 Comparable 和 Comparator 都是消费者。雖然像一個口訣,但是千萬不要背。