【发布时间】:2018-05-08 23:46:29
【问题描述】:
假设我有以下结构:
java.lang.Object
class A extends Object { public boolean mA() {return true;} }
class B extends A { public boolean mB() {return false;} }
现在我正在编写一个 main 方法来使用它。 我对以下概念很好:(从超级的get方法返回的'Object'类型)
public static void m1(List<? super A> l ) {
l.get(0).toString();
}
因为我可以使用
来调用它m1(new ArrayList<A>());
m1(new ArrayList<Object>());
我对此也很好:('A' 类型从扩展的 get 方法返回)
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 非常没用,因为它只在测试方法中接受“null”)。无论如何,我正在寻找这样的练习,无论如何我都学会了。
Predicate<? extends A> pExtends2 = (B b) -> b.mB();
【问题讨论】:
-
好问题!我从来没有注意到这一点,但它似乎真的很有趣!我希望我能提供帮助,但我对 Java 中遗传学的实现知之甚少。但是要意识到泛型都是编译时的,它们在字节码生成期间被简化为对象。泛型只是为了方便程序员使用。
-
嗯,它不可能是
Object,因为你打电话给mA()。尝试拨打toString()看看你会得到什么。
标签: java generics lambda extends super