Ваше понимание верно. Например, функция, которая принимает Predicate<? super Employee>
(как в вашем примере ArrayList<Employee>
), также может принимать Predicate<Object>
подобно Objects::nonNull
. Концептуально это имеет смысл по следующей причине: «Мы (класс) берем Predicate
, который действует на нас или на любой из (переходных) суперклассов нашего самого себя, потому что у нас есть is-a отношения с этими суперклассами. "То есть функция, которая принимает любой Object
и возвращает boolean
, эквивалентно применима к Employee
, потому что Employee
is-a Object
, и поэтому ее можно применятьэта функция для Employee
. Производный класс не является точно таким же, как базовый класс, но предикат (логический тест) по-прежнему применяется к производному классу, поскольку имеет смысл говорить о производном классе как о базовом классе.
Давайте рассмотрим пример: Employees
может быть получено из Person
. Если Person
можно протестировать с помощью Predicate<Person>
, называемого hasJob
, то логично также иметь возможность проверить Employees
для hasJob
. Способность этой функции принимать Predicate<? super Employee>
вместо Predicate<Employee>
требуется для поддержания способности функции принимать логически обоснованный предикат. С другой стороны, если вы ожидаете, что Employee
s будет проверено только для некоторого свойства, вы можете вместо этого принять только Predicate<Employee>
, поскольку это соответствует логической обоснованности только Employee
и его производных классов, обладающих способностьюбыть проверенным на это свойство.
Чтобы быть на 100% ясным о том, что здесь происходит:
Predicate<? super Employee>
принимает Predicate
, что test
s Employee
и любой суперкласс из Employee
, , включая Object
Predicate<Employee>
принимает Predicate
, что test
s Employee
и любой подкласс из Employee
, который исключает Object
Учитывая эту иерархию классов: SalariedEmployee is-a Employee is-a Person
, вот что происходит (P - сокращение для Predicate
):
╔══════════════════╦═══════════╦═══════════════════╦═════════════╦═════════════════════╦═════════════════════╦═════════════════════════════╗
║ Type ║ P<Person> ║ P<? super Person> ║ P<Employee> ║ P<? super Employee> ║ P<SalariedEmployee> ║ P<? super SalariedEmployee> ║
╠══════════════════╬═══════════╬═══════════════════╬═════════════╬═════════════════════╬═════════════════════╬═════════════════════════════╣
║ Person ║ Accept ║ Accept ║ Reject ║ Accept ║ Reject ║ Accept ║
║ Employee ║ Accept ║ Reject ║ Accept ║ Accept ║ Reject ║ Accept ║
║ SalariedEmployee ║ Accept ║ Reject ║ Accept ║ Reject ║ Accept ║ Accept ║
║ Object ║ Reject ║ Accept ║ Reject ║ Accept ║ Reject ║ Accept ║
╚══════════════════╩═══════════╩═══════════════════╩═════════════╩═════════════════════╩═════════════════════╩═════════════════════════════╝
Обратите внимание, что Accept/Reject
обозначает типы, которые можно вводить в Predicate
, а не фактический результат Predicate
.