Может ли компилятор Java вывести тип универсальной статической функции из ее контекста в качестве аргумента другой универсальной статической функции?
Например, у меня есть простой класс Pair:
public class Pair<F, S> {
private final F mFirst;
private final S mSecond;
public Pair(F first, S second) {
mFirst = checkNotNull(first);
mSecond = checkNotNull(second);
}
public static <F, S, F1 extends F, S1 extends S> Pair<F, S> of(F1 first, S1 second) {
return new Pair<F, S>(first, second);
}
public F first() {
return mFirst;
}
public S second() {
return mSecond;
}
// ...
}
И у меня есть следующая общая статическая функция:
public static <F, P extends Pair<F, ?>> Function<P, F> deferredFirst() {
return (Function<P, F>)DEFERRED_FIRST;
}
private static final Function<Pair<Object, ?>, Object> DEFERRED_FIRST =
new Function<Pair<Object,?>, Object>() {
@Override
public Object apply(Pair<Object, ?> input) {
return input.first();
}
};
, которую я хочу использовать следующим образом ( Collections2.transform из Google Guava ):
List<Pair<Integer, Double>> values = ...
Collection<Integer> firsts = Collections2.transform(values,
Pair.deferredFirst());
На что жалуется компилятор:
The method transform(Collection<F>, Function<? super F,T>) in the type
Collections2 is not applicable for the arguments
(List<Pair<Integer,Double>>, Function<Pair<Object,?>,Object>)
Таким образом, похоже, что компилятору не удалось распространить типы, выведенные для transform (), на deferredFirst (), поскольку он считает, что они являются объектами.
Заставляет компилятор понимать типы любым из следующих способов:
Function<Pair<Integer, ?>, Integer> func = Pair.deferredFirst();
Collection<Integer> firsts = Collections2.transform(values, func);
Collection<Integer> firsts = Collections2.transform(values,
Pair.<Integer, Pair<Integer, ?>>deferredFirst());
Можно ли изменить сигнатуру любой функции, чтобы компилятор мог выводить / распространять типы?
Редактировать: Для богемского, вот возможный метод, в котором приведенный выше пример может быть использован в:
public static int sumSomeInts(List<Pair<Integer, Double>> values) {
Collection<Integer> ints = Collections2.transform(values,
Pair.deferredFirst());
int sum = 0;
for(int i : ints)
sum += i;
return sum;
}