Предположим, у меня есть следующая структура:
java.lang.Object
class A extends Object { public boolean mA() {return true;} }
class B extends A { public boolean mB() {return false;} }
Сейчас я пишу основной метод для его использования.
Я в порядке с понятиями ниже: (тип 'Object', возвращаемый из метода get для super)
public static void m1(List<? super A> l ) {
l.get(0).toString();
}
, так как я могу позвонить, используя
m1(new ArrayList<A>());
m1(new ArrayList<Object>());
У меня тоже все нормально: (тип 'A' возвращается из метода get для extends)
public static void m2(List<? extends A> l ) {
l.get(0).mA();
}
так как я могу позвонить, используя
m2(new ArrayList<A>());
m2(new ArrayList<B>());
Наконец, мой вопрос: почему приведенное ниже определение с «super» получает тип «A» в качестве параметра вместо Object?
Predicate<? extends A> p1 = a -> a.mA(); // ok
Predicate<? super A> p2 = a -> a.mA(); // why is it of type 'A' too??
Я думал, что это превратится в нечто вроде (я знаю, что приведенный ниже код недействителен ... Я просто думаю, что это будет похоже на это).
PredicateImpl<T super A> {
public boolean test(T t);
}
Я также проверил декомпилированный класс, но не получил никакой новой подсказки. Может кто-нибудь сказать мне, что происходит под капотом? Я уже читал обсуждения PECS, но это не помогло мне в этом конкретном вопросе.
Заранее спасибо! ;)
===== Редактирование с дополнительным кодом после получения ответа =====
Predicate<? super A> pSuper = a -> a.mA();
Predicate<? extends A> pExtends = a -> a.mA(); // ?? A ??
Predicate<Object> pObject = o -> o.equals(null);
Predicate<A> pA = a -> a.mA();
Predicate<B> pB = b -> b.mB();
pSuper = pObject;
pSuper = pA;
pSuper = pB; // compiler error
pExtends = pObject; // compiler error
pExtends = pA;
pExtends = pB;
Интересный альтернативный синтаксис (хотя я думаю, что Predicate <& quest; extends Anything> довольно бесполезен, поскольку он принимает только 'null' в тестовом методе). Во всяком случае, я нахожу такие упражнения, и я должен научиться этому независимо.
Predicate<? extends A> pExtends2 = (B b) -> b.mB();