在下面的例子中,编译器在行上抱怨:handler.handle(info); 有错误:
Event.Handler类型中的方法句柄(捕获#3-of?extends T)不适用于参数(T)
即使在这种情况下处理程序被声明为接受T的任何子类,编译器也不会接受类型为T本身的方法调用.
public class Event<T> {
public interface Handler<U> {
public void handle(U info);
}
private final Handler<? extends T> handler;
private final T info;
public Event(Handler<? extends T> handler, T info) {
this.handler = handler;
this.info = info;
}
public void doEvent() {
handler.handle(info);
}
}
Run Code Online (Sandbox Code Playgroud)
此示例的另一个有趣功能是,如果键入:"handler".在eclipse中,给出了以下建议"handle(null info):void".不知何故,类型'null'被建议为可接受的类型.
从命令行使用javac进行编译仍会产生类似的错误,因此这不仅仅是一个eclipse问题.
我的问题:
null类型?它被声明为某种类型的Handler,它扩展了T. Imagine T是Object,你传入了一个Handler<String>.从构造函数的角度来看这很好 - 但是你不会期望能够打电话handler.handle(new Object())给你吗?一个Handler<String>只能期望处理字符串,而不是任意对象.
基本上你在寻找逆变而不是协方差,所以你需要:
private final Handler<? super T> handler;
private final T info;
public Event(Handler<? super T> handler, T info) {
this.handler = handler;
this.info = info;
}
Run Code Online (Sandbox Code Playgroud)