Ответ
PECS (Producer Extends, Consumer Super) — это мнемоническое правило для безопасного использования подстановочных типов (wildcards) ? extends и ? super в Java Generics. Оно определяет, какую операцию (чтение или запись) можно безопасно выполнять с коллекцией.
1. Producer Extends (? extends T)
Используется, когда коллекция производит (отдает) элементы типа T. С такой коллекцией можно безопасно читать, но нельзя добавлять новые элементы (кроме null).
// Коллекция — производитель Number
List<? extends Number> numbers = Arrays.asList(1, 2.5, 3L);
// БЕЗОПАСНО: Чтение. Все элементы можно трактовать как Number.
Number first = numbers.get(0);
Double second = (Double) numbers.get(1); // После проверки
for (Number n : numbers) { /* ... */ }
// НЕБЕЗОПАСНО / ОШИБКА КОМПИЛЯЦИИ: Запись.
// numbers.add(10); // Нельзя добавить Integer
// numbers.add(3.14); // Нельзя добавить Double
// Компилятор не знает точный тип внутри List.
2. Consumer Super (? super T)
Используется, когда коллекция потребляет (принимает) элементы типа T. В такую коллекцию можно безопасно записывать объекты T (и его подтипы), но читать можно только как Object.
// Коллекция — потребитель Integer
List<? super Integer> integers = new ArrayList<Number>();
// БЕЗОПАСНО: Запись. Можно добавлять Integer и его подтипы.
integers.add(42);
integers.add(100);
// НЕБЕЗОПАСНО: Чтение с конкретным типом.
// Integer i = integers.get(0); // Ошибка компиляции
// Компилятор знает только, что это некий супертип Integer.
// БЕЗОПАСНО: Чтение как Object.
Object obj = integers.get(0);
Итог:
- Для чтения используй
? extends T(коллекция — производитель). - Для записи используй
? super T(коллекция — потребитель). Это правило критически важно для написания типобезопасных обобщенных методов, таких какCollections.copy().