Следующая подпись действительна и обычно используется в Scala:
trait Collection[A] {
def reduceLeft [B >: A] (f: (B, A) => B): B
}
Однако, поскольку >:
является Scala-эквивалентом super
в Java, моей первой идеей преобразовать эту подпись (заменив тип функции на BiFunction
и используя аннотации дисперсии Use-Site, также известные как Bounded Wildcards), будет
interface Collection<A> {
<B super A> B reduceLeft(BiFunction<? super B, ? super A, ? extends B> mapper)
}
Но о нет! Компилятор жалуется на токен super
в <B super A>
, потому что у вас не может быть переменных типа с нижней границей! Теперь, как мне написать этот метод в коде Java, не возвращаясь во времени к тому времени, когда в мире Java не существовало дженериков?
Да, я знаю, что вы думаете, что я мог бы использовать B extends A
, но это не одно и то же, как показывает моя реализация:
public <R extends E> R reduceLeft(BiFunction<? super R, ? super E, ? extends R> mapper)
{
if (this.isEmpty())
{
return null;
}
Iterator<E> iterator = this.iterator();
R first = iterator.next(); // doesn't work, but would if R was a super-type of E (R super E)
while (iterator.hasNext())
{
mapper.apply(first, iterator.next());
}
return first;
}
Вместо этого мне пришлось использовать эту немного более ограниченную версию:
public E reduceLeft(BiFunction<? super E, ? super E, ? extends E> mapper)
{
if (this.isEmpty())
{
return null;
}
Iterator<E> iterator = this.iterator();
E first = iterator.next();
while (iterator.hasNext())
{
first = mapper.apply(first, iterator.next());
}
return first;
}
A
. Поэтому я переписал это на<A, B super A> B reduceLeft(BiFunction<? super B, ? super A, ? extends B> mapper)
. Но это все еще не работает. Однако это работает сextends
. Тогда я подумал,B super A
это то же самое, что иA extends B
? Я думаю, что они одинаковы... так что вы можете написать<B, A extends B> B reduceLeft(BiFunction<? super B, ? super A, ? extends B> mapper)
- person xp500   schedule 15.07.2015