我有以下代码片段,乍一看它应该可以工作,但是我收到一个非常有趣的错误:
'apply(capture<? extends Generic.MyClass>)' in 'java.util.function.Function' cannot be applied to '(capture<? extends Generic.MyClass>)'
此错误发生在这里:function.apply(wrapper.value);
我想念什么?
public class Generic {
public static void main(String[] args) {
Wrapper wrapper = new Wrapper<>(new MyClass());
}
private static void method(Wrapper<? extends MyClass> wrapper) {
Function<? extends MyClass, String> function = (MyClass m) -> m.getClass().toString();
function.apply(wrapper.value);
}
static class Wrapper<T extends MyClass> {
private final T value;
Wrapper(T value) {
this.value = value;
}
}
static class MyClass {
}
}
答案 0 :(得分:4)
将变量类型更改为(*):
Function<MyClass, String>
? extends MyClass
表示此函数接受MyClass
的特定子类,但是您只是不知道哪个子类。
尽管错误消息使它们看起来像是相同的类型,但事实并非如此:每个? extends MyClass
都引用了不同的(但特定的)类型。
您唯一可以安全传递给此函数的内容是文字null
。
首字母缩略词PECS告诉您extends
用于生产者方法(例如,“包装器产生价值”)。不适用于使用者方法(例如“函数接受T作为参数”):这就是super
的用途。
(*)或仅使用wrapper.value.getClass().toString();
,而不必费心声明函数。
答案 1 :(得分:0)
您可以使方法通用:
public class Main {
public static void main(String[] args) {
Wrapper wrapper = new Wrapper<>(new MyClass());
}
private static <T extends MyClass> void method(Wrapper<T> wrapper) {
Function<T, String> function = (T m) -> m.getClass().toString();
function.apply(wrapper.value);
}
static class Wrapper<T extends MyClass> {
private final T value;
Wrapper(T value) {
this.value = value;
}
}
static class MyClass {
}
}