Дженерики Java PECS
Я знаю, что означает PECS.
Продюсер продлевает,Consumer Super.
дело в том, откуда мне знать, является ли он потребителем или производителем?
Также этот код соответствует "PECS"
public class Tree<T> {
//List of branches for this tree
private List<Tree<? super T>> branch = new ArrayList<Tree<? super T>>();
public Tree(T t){ this.t = t; }
public void addBranch(Tree< ? super T> src){ branch.add(src); }
public Tree<? extends T> getBranch(int branchNum){
return (Tree<? extends T>) branch.get(branchNum);
}
private T t;
}
3 ответа
Хорошая мнемоника, которую вы можете использовать, это представить returns
за extends
а также accepts
за super
,
Так что Tree<? extends T>
читает Tree<? returns T>
Это означает, что вы можете вызывать методы в Tree
это возвращение T
, но не методы, которые принимают T
в качестве типа аргумента.
- Производитель ссылается на тип возвращаемого значения метода.
- Потребитель относится к типу параметра метода.
Следующее немного прояснилось в моей голове. Надеюсь, это поможет вам.
Представьте себе список элементов какого-то неизвестного типа X, и есть некоторая логика, которая сканирует список как элементы типа X явно (после того, как список построен). Давайте назовем эту логику Logic1.
Если вы собираетесь сканировать этот список как объекты типа T, существует требование, чтобы X был получен из T в некоторой форме. В противном случае у вас будут проблемы. Следовательно, ваша подпись должна быть:
void scan(List<? extends T>);
Если вы собираетесь добавить объекты типа T в список, существует требование, чтобы T был получен из X. В противном случае у Logic1, упомянутой выше, будут проблемы. Следовательно, ваша подпись должна быть:
void add(List<? super T>);
Обратите внимание, что, насколько я понимаю, и "scan", и "add" могут фактически удалять записи из списка. Я нахожу PECS немного запутанным. "Производитель" и "потребитель" происходит с точки зрения списка. Я не люблю смотреть на список как на активную вещь, которая может выполнять логику. Мне нравится SEAS (Scan Extends и Add Supers). Просто мои 2 цента.
Когда метод читает или перебирает элементы в коллекции, он становится потребителем, а когда он добавляется в коллекции, он является производителем.