Я готовлюсь к сертификату OCP и натолкнулся на идею подстановочного знака с нижним ограничением. Если я правильно понимаю, подстановочный знак с нижним ограничением используется, когда мы хотим, чтобы Java знала, что «ограниченный тип» всегда можно добавить в нашу универсальную коллекцию.
Например:
public static void addInteger(List<? super Integer> list, Integer i)
{
list.add(i);
}
public static void main(String[] args)
{
List<Number> list = new ArrayList<>();
addInteger(list, 100);
addInteger(list, 200);
System.out.println(list); // [100,200]
}
Поскольку "? Super Integer" указывает, что тип должен быть Integer или его суперклассом, добавление Integer в список будет работать в каждом случае.
Однако этот код все еще компилируется и работает как обычно:
public static void main(String[] args)
{
Predicate<? super String> pred = s -> s.startsWith("M"); // still compiles
System.out.println(pred.test("Mon")); // Output true
}
Теперь у нас есть предикат, который будет принимать 1 параметр, который является строкой или ее суперклассом, но мы не уверены, что это на самом деле строка или нет (что, если это просто объект?). Однако мы все равно можем получить доступ к методу startsWith()
, например, s
на самом деле является строкой.
Почему это происходит? Пожалуйста, объясните мне.