Java Generics:方法X不适用于参数

Can*_*ner 6 java

EventHandler.java:

public abstract class EventHandler<E extends EventArgs> { 
    public abstract void HandleEvent(Object sender, E e);
}
Run Code Online (Sandbox Code Playgroud)

Observers.java:

public class Observers<E extends EventArgs> {

    private CopyOnWriteArrayList<EventHandler<? extends E>> mListeners = new CopyOnWriteArrayList<EventHandler<? extends E>>();

    public void dispatchEvent(Object sender, E args) {
        if (mListeners != null) {
            for (EventHandler<? extends E> listener : mListeners) {
                listener.HandleEvent(sender, args);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以下行:

listener.HandleEvent(sender, args);
Run Code Online (Sandbox Code Playgroud)

原因:

EventHandler类型中的方法HandleEvent(Object,capture#3-of?extends E)不适用于参数(Object,E)

有人怎么解决这个问题?

EDIT1 原因? super E对我不起作用是我在Observers类中有以下方法:

public void addListener(EventHandler<? super E> listener) {
mListeners.add(listener);
}
Run Code Online (Sandbox Code Playgroud)

这导致:

参数类型CopyOnWriteArrayList>中的方法add(EventHandler)不适用于参数(EventHandler)

EDIT2

究其原因,从变化? super EE不适合我,因为这一点: X是不适用于Y,当X Y延伸的论点

它已经是那样了,但这既不起作用:(

pto*_*mli 3

你为什么宣称mListeners是 ~? extends E而不是 just E

如果你使用

private CopyOnWriteArrayList<EventHandler<E>> mListeners = new CopyOnWriteArrayList<EventHandler<E>>();
Run Code Online (Sandbox Code Playgroud)

它会起作用的。

或者采用PECS(生产者扩展,消费者超)。正如其他人所建议的

private CopyOnWriteArrayList<EventHandler<? super E>> mListeners = new CopyOnWriteArrayList<EventHandler<? super E>>();
Run Code Online (Sandbox Code Playgroud)

以及对循环的相关更改for

编辑:一个更完整的例子。这不会显示任何警告或错误,并且根据您所提供的内容,这是可行的。

public static class Sandbox {
    public static interface EventArgs {}
    public static abstract class EventHandler<E extends EventArgs> { 
        public abstract void HandleEvent(Object sender, E e);
    }
    public static class Observers<E extends EventArgs> {

        private CopyOnWriteArrayList<EventHandler<? super E>> mListeners
                = new CopyOnWriteArrayList<EventHandler<? super E>>();

        public void dispatchEvent(Object sender, E args) {
            if (mListeners != null) {
                for (EventHandler<? super E> listener : mListeners) {
                    listener.HandleEvent(sender, args);
                }
            }
        }
        public void addListener(EventHandler<? super E> listener) {
            mListeners.add(listener);
        }        
    }
}
Run Code Online (Sandbox Code Playgroud)