Java泛型 - 接受<?的方法不允许使用类型为T的对象.延伸T>

Gar*_*dge 2 java generics

在下面的例子中,编译器在行上抱怨: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问题.

我的问题:

  1. 这是java编译器的正确行为吗?
  2. 如果这是正确的行为,我应该怎么做以保持我的事件类的类型安全?
  3. 什么是null类型?

Jon*_*eet 5

它被声明为某种类型的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)