【发布时间】:2019-05-01 20:17:33
【问题描述】:
针对以下三种情况:
void check1(Function<Parent, String> function) {
Parent p = new Parent();
function.apply(p); // compiles fine
Child c = new Child();
function.apply(c); // compiles fine
}
void check2(Function<? super Parent, String> function) {
Parent p = new Parent();
function.apply(p); // compiles fine
Child c = new Child();
function.apply(c); // compiles fine
}
void check3(Function<? extends Parent, String> function) {
Parent p = new Parent();
function.apply(p); // compile time error
Child c = new Child();
function.apply(c); // compile time error
}
在第三种情况下,对于父对象或子对象传递给函数的两种情况,我都会收到类似的编译时失败:
类型中的方法 apply(capture#21-of ? extends Parent) 功能不适用 对于参数(父)
到目前为止,我的理解是:extends 确实意味着“是或扩展”,但上述情况导致我进行以下查询:
- 为什么
Function<? extends T>不接受子对象、父对象? - 其次是
Function<? super T>接受子对象和父对象 由于父引用可以容纳子对象 (Base obj=new Child()) ?
编辑:
我了解集合(例如列表)中的 PECS 问题,如 here 所述,因为 List<? extends Parent> 可能会得到List<GrandChild> 的reference。现在,如果我们尝试在其中添加Child object,如果之前没有被编译器捕获,将会导致运行时错误。
同样,函数式接口的行为也相同,以及如何 参考保持在这里?
rgettman 的示例解释了该功能,但与集合相比,只是想要更清晰的图片。
此外,这很好,但似乎 PECS(扩展不能消耗任何东西) 不应该按字面意思理解:
<T extends Parent> void check4(List<T> myList, Function<T, String> func) {
func.apply(myList.get(0)); // compiles successfully
}
【问题讨论】:
标签: java generics inheritance casting functional-programming