Согласно книге «Эффективная Java» Джошуа Блоха, существует правило о том, как использовать ограниченные подстановочные знаки в дженериках. Это правило - PECS (Producer-Extends, Comsumer-Super). Когда я изучаю следующий пример:Java Generics (ограниченные подстановочные знаки)
Stack<Number> numberStack = new Stack<Number>();
Iterable<Integer> integers = ... ;
numberStack.pushAll(integers);
Я понимаю, что это правило идеально подходит в этом примере. Я должен объявить метод pushAll
, как в следующем примере:
// Wildcard type for parameter that serves as an E producer
public void pushAll(Iterable<? extends E> src) {
for (E e : src)
{
push(e);
}
}
Но что произойдет, если у меня есть следующий пример?
Stack<Integer> integerStack = new Stack<Integer>();
Iterable<Number> numbers = ... ;
integerStack.pushAll(numbers);
Я должен объявить pushAll
как это следующим образом:
public void pushAll(Iterable<? super E> src) {
for (E e : src)
{
push(e);
}
}
Согласно PECS править выше заявление является неправильным. Но я хочу иметь Stack
Integer
s и пройти к этому Stack
a Number
. Почему бы не сделать это?
Почему я должен всегда использовать ключевое слово extends
? Почему использование super
неверно?
Конечно же то же, что и для comsumer. Почему потребитель всегда должен быть super
?
PS: Чтобы быть более конкретным, вы можете найти этот вышеприведенный пример в секторе «Пункт 28» упомянутой книги.
Когда вы нажимаете - вы выступаете в качестве консультанта, а не производителя, поэтому вам нужно использовать ключевое слово super. – Alexandr
Согласно книге, я продюсер. Комментарий «Тип подстановочного знака для параметра, который служит производителем E», является автором. Писатель говорит, что я comsumer, когда я тяну за Stack! Первые два образца взяты из книги (copy-paste). Третий пример - мой. – LiTTle