Возможно, это прояснит ситуацию:
Function<Fruit, Integer> costFunc = Fruit::getCost;
Function<? super Fruit, ? extends Comparable<?>> fx = costFunc;
Каждый объект с типизированной c типизацией имеет точные аргументы типа. Хотя вы можете сослаться на Функция как Function<? super Fruit, …>
, не существует такого объекта как объект. Есть функция , функция и функция , но ни один существующий объект не может иметь подстановочный тип (то есть тип, который использует знак вопроса). ?
- это только способ сообщить компилятору, что вы не уверены , каков фактический тип generi c объекта.
В приведенном выше коде компилятор видит, что fx
объявлен как Function<? super Fruit, ? extends Comparable<?>>
. Компилятор не знает, каков фактический тип generi c входного параметра функции, потому что вы сказали ему, что это некоторый специфицированный c тип , который может быть Fruit, или любой класс или интерфейс наследуется Fruit.
Таким образом, компилятор не знает, безопасно ли передавать Product в метод apply
. Что если fx
содержит в качестве первого аргумента функцию, для которой требуется фрукт, а не какой-либо продукт? То есть Function<Fruit, …>
(что показывает пример)?
Если вы хотите объявить функцию, которая принимает Fruit или любой супертип Fruit, вы бы написали Function<Object, …>
без использования подстановочных знаков вообще.