РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
91 of 1163 menu

Подстановка ? super

Подстановка ? super - это wildcard-тип с нижней границей в обобщённых типах Java. Она означает «неизвестный тип, который является супертипом указанного типа». Такой wildcard применяется, когда нужно безопасно записывать значения в обобщённую структуру. В первом параметре указывается ключевое слово super, а во втором - тип, который выступает нижней границей.

Wildcard ? super противоположен по смыслу wildcard ? extends. Если ? extends позволяет безопасно читать значения, то ? super позволяет безопасно записывать значения. Это связано с принципом PECS: Producer Extends, Consumer Super.

Синтаксис

List<? super Type> Consumer<? super Type> Comparable<? super Type>

Пример

Давайте запишем значения в список с типом List<? super Integer>. Такой список может быть списком объектов Integer, Number или Object:

import java.util.List; import java.util.ArrayList; public class Main { public static void main(String[] args) { List<Number> nums = new ArrayList<>(); addNumbers(nums); System.out.println(nums); } public static void addNumbers(List<? super Integer> list) { list.add(1); list.add(2); list.add(3); } }

Результат выполнения кода:

[1, 2, 3]

Пример

Давайте передадим в метод список объектов Object, так как Object является супертипом для Integer:

import java.util.List; import java.util.ArrayList; public class Main { public static void main(String[] args) { List<Object> objects = new ArrayList<>(); addNumbers(objects); System.out.println(objects); } public static void addNumbers(List<? super Integer> list) { list.add(1); list.add(2); list.add(3); } }

Результат выполнения кода:

[1, 2, 3]

Пример

Особенность ? super в том, что из такой структуры нельзя безопасно читать значения, потому что компилятор знает только верхнюю границу в виде Object. Давайте убедимся, что добавление работает, а результат чтения имеет тип Object:

import java.util.List; import java.util.ArrayList; public class Main { public static void main(String[] args) { List<Number> nums = new ArrayList<>(); nums.add(10); Object res = getFirst(nums); System.out.println(res); } public static Object getFirst(List<? super Integer> list) { list.add(1); return list.get(0); } }

Результат выполнения кода:

10

Пример

Давайте напишем обобщённый метод, который копирует элементы из одного списка в другой с использованием ? super для приёмника:

import java.util.List; import java.util.ArrayList; public class Main { public static void main(String[] args) { List<Integer> src = List.of(1, 2, 3, 4, 5); List<Number> dst = new ArrayList<>(); copy(src, dst); System.out.println(dst); } public static <T> void copy(List<? extends T> src, List<? super T> dst) { for (T item : src) { dst.add(item); } } }

Результат выполнения кода:

[1, 2, 3, 4, 5]

Смотрите также

  • подстановка ? extends,
    которая задаёт верхнюю границу типа
  • подстановка ?,
    которая обозначает неизвестный тип
  • ключевое слово super,
    которое задаёт нижнюю границу в обобщениях
  • контравариантность Contravariant,
    которая лежит в основе подстановки ? super
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить