Java: недопонимание дженериков и подстановочных знаков - PullRequest
1 голос
/ 09 февраля 2020

Рассмотрим следующий код:

public final class Algorithm {
    public static <T extends Comparable<? super T>>
        T max(List<? extends T> list, int begin, int end)
    {
            // ...
    }
}

Является ли объявление параметра List<? extends T> list равным List<? extends Comparable<? super T>> list?

1 Ответ

3 голосов
/ 09 февраля 2020

Существует очень небольшая разница.

List<? extends T> означает

a List объектов неизвестного типа, которые являются либо T, либо вложенными элементами T

List<? extends Comparable<? super T>> означает

a List объектов неизвестного типа, которые являются либо Comparable<? super T>, либо реализацией Comparable<? super T>.

Давайте рассмотрим эту иерархию классов: A и B являются несвязанными классами, которые оба реализуют Comparable<A> и оба являются окончательными. Да, я знаю, что эта ситуация надумана.

Если из возвращаемого значения T выведено значение A, вы можете только передать List<A> параметру типа List<? extends T>. Однако вы можете передать List<A>, а также List<B> параметру типа List<? extends Comparable<? super T>>.

Вот пример, демонстрирующий мою точку зрения:

public static void main(String[] args) {
    List<A> aList = Collections.singletonList(new A());
    List<B> bList = Collections.singletonList(new B());
    A a = f(aList);
    A b = f(bList); // doesn't compile
    A c = g(bList);
    A d = g(bList);
}

public static <T extends Comparable<? super T>> T f(List<? extends T> list) {
    return null;
}

public static <T extends Comparable<? super T>> T g(List<? extends Comparable<? super T>> list) {
    return null;
}

final class A implements Comparable<A> {
    @Override
    public int compareTo(A o) {
        return 0;
    }
}
final class B implements Comparable<A> {
    @Override
    public int compareTo(A o) {
        return 0;
    }
}

В действительности хотя очень редко случаются такие вещи, как class B implements Comparable<A>, , поэтому по большей части эти два типа совпадают.

...