Итак, я в настоящее время изучает лямбда-выражения и просто наткнулся на пример с родовыми функциональными intefaces:лямбда-выражения и общий интерфейс
@FunctionalInterface
public interface Mapper<T> {
int map(T source);
public static <U> int[] mapToInt(U[] list, Mapper<? super U> mapper) {
int[] mappedValues = new int[list.length];
for(int i = 0; i< list.length; i++) {
mappedValues[i] = mapper.map(list[i]);
}
return mappedValues;
}
}
и тестовый код
public static void main(String[] args) {
System.out.println("Mapping names to their lengths:");
String[] names = {"David", "Li", "Doug"};
int[] lengthMapping = Mapper.mapToInt(names, (String name) -> name.length());
printMapping(names, lengthMapping);
}
public static void printMapping(Object[] from, int[] to) {
for(int i = 0; i < from.length; i++) {
System.out.println(from[i] + " mapped to " + to[i]);
}
}
Итак, что беспокоит me, в этом примере мы передаем экземпляр функционального интерфейса Mapper
в качестве второго аргумента в методе mapToInt
в тестовом коде. Но, каково было бы значение формального параметра <T>
из Mapper
, в этом примере? Кажется, что это работает, но почему компилятор может понять это, если не задал аргумент для формального параметра?
Это возможно потому, что абстрактный метод:
int map(T source);
использует T
параметра, и на основе выражения аргумента лямбды, использует это в качестве вещественного типа для T
?
Также, второй параметр в mapToInt: Mapper<? super U> mapper
, тот же вопрос, каково было бы значение в этом примере для типа Mapper
, <? super U>
?